LoginSignup
1
1

More than 5 years have passed since last update.

PureScript by Example の 7.5, 7.6, 7.7, 7.8 を読む

Posted at

この記事は (bouzuya) PureScript Advent Calendar 2016 の 25 日目。 (bouzuya) PureScript Advent Calendar 2016 は bouzuya の PureScript 学習の記録だ。

概要

PureScript by ExamplePureScript Language GuidePursuit を見ながら進めていく。

今日は 7.5, 7.6, 7.7, 7.8 を読む。ソースコードの例は purescript-book の exercises/chapter7 にある。

※注意事項: 英語と日本語訳では大きな差異がある。0.10.x に対応している英語の側で進める。

この章のおさらい

Applicative 型クラスと Traversable 型クラスを見るらしい。 Control.Applylift3 の実装を基に Functor 型クラスと Apply 型クラスの関数を調べた。

Pursuit:

PureScript by Example 7.5

Applicative 型クラス。 Apply に加えて pure を持つ。 MaybeApplicative のインスタンスでもある。

class Apply f <= Applicative f where
  pure :: forall a. a -> f a

instance applicativeMaybe :: Applicative Maybe where
  pure x = Just x

a -> f a なので、 fa を包んで返す感じ。 Maybe だと Just するだけ。

Pursuit:

PureScript by Example 7.6

なんだかふわふわした説明だ……。

PureScript の関数は純粋で副作用をサポートしていないけど、 applicative functor は関手 (functor) f によってエンコードされたなんらかの副作用をサポートする、より大きなプログラミング言語にできる。ふむー。

Maybe によって Nothing を導入できるってのがその例らしい。

pure はその大きなプログラミング言語に値を持ち上げるし、 mapapply で関数も、と。ふむー。

分かるような分からないような……。

PureScript by Example 7.7

> import Prelude
> let fullName first middle last = last <> ", " <> first <> " " <> middle

上記のような fullName をつくって Maybe のために使うことは難しくないと分かった。7.7 ではエラーの内容を知るために Either を使う例が挙げられている。

module Main where

import Prelude
import Data.Maybe
import Data.Either

fullName :: String -> String -> String -> String
fullName first middle last = last <> ", " <> first <> " " <> middle

withError :: forall a. Maybe a -> String -> Either String a
withError Nothing  err = Left err
withError (Just a) _   = Right a

fullNameEither :: Maybe String -> Maybe String -> Maybe String -> Either String String
fullNameEither first middle last =
  fullName <$> (first  `withError` "First name was missing")
           <*> (middle `withError` "Middle name was missing")
           <*> (last   `withError` "Last name was missing")

どれかが Left なら最終結果も Left 。すべて Right なら Right

実用の面で問題があるとすれば、最初のエラーしか取れないこと。その解決策もこの章の後半で出てくるらしい。

PureScript by Example 7.8

ここまでで a -> a -> a -> List a が書けるなら f a -> f a -> f a -> f (List a) は難しくないことが分かっている。 f a -> f a -> f a を固定ではなく可変にして List (f a) にすると List (f a) -> f (List a) にできる。ふむ。

module Main where

import Prelude
import Data.List

combineList :: forall f a. Applicative f => List (f a) -> f (List a)
combineList Nil = pure Nil
combineList (Cons x xs) = Cons <$> x <*> combineList xs

うん。そうだね。

> import Data.List
> import Data.Maybe
> import Main
> combineList (fromFoldable [Just 1, Just 2, Just 3])
(Just (1 : 2 : 3 : Nil))

> combineList (fromFoldable [Just 1, Nothing, Just 2])
Nothing

確かに動く。Maybe でなくても動くらしい。そりゃ Applicative だもんな。

combineList :: forall f a. Applicative f => List (f a) -> f (List a)

また Traversable の話の中でこの combineList が出てくるらしい。ふむ。

まとめ

とりあえず Applicative の例まで。

すごく途中だけど、これで (bouzuya) PureScript Advent Calendar 2016 の 25 日はおしまい。「 PureScript by Example を読む」に関しては、ペースは落ちるけど、章単位で書くようにして最後まで進めるつもりだ。

次回以降の TODO

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1