Haskellやっぱ難しいよ。難しいって。

非決定性計算を見た。
Schemeで出てきたんだけどググったらHaskellの例があったので、見てみた。
SICPのambのあたりで

import Control.Monad

solve = do baker <- [1, 2, 3, 4, 5]
           cooper <- [1, 2, 3, 4, 5]
           fletcher <- [1, 2, 3, 4, 5]
           miller <- [1, 2, 3, 4, 5]
           smith <- [1, 2, 3, 4, 5]
           guard $ distinct [baker, cooper, fletcher, miller, smith]
           guard $ baker /= 5
           guard $ cooper /= 1
           guard $ fletcher /= 1 && fletcher /= 5
           guard $ miller > cooper
           guard $ abs (smith - fletcher) /= 1
           guard $ abs (fletcher - cooper) /= 1
           [baker, cooper, fletcher, miller, smith]

distinct :: Eq a => [a] -> Bool
distinct [] = True
distinct (x:xs) = all (/=x) xs && distinct xs

main :: IO()
main = print solve

実行結果: [3,2,4,5,1]

↑こんなの。
すげぇ。条件だけ並べたら結果が返ってきてる。
宣言的だ。すげぇ。
でもなんで結果がでるのかさっぱり分からない。

非決定性計算ってなんだ??まずそこが分からない。
しょうがないよね。文系だもの。(いいわけ)

調べる調べる。
ふむ。非決定性計算って総当りなのか。

とりあえず、コードの断片が分からなければ理解も進むわけがない。

たぶんリストモナドとguardとMonadPlusが分かれば理解できるんじゃなかろうか??
と思って、調べる。

Listモナドの>>=はconcatMapらしい。
いかん。concatMapってなんだ??

:t concatMap

 っと。

concatMap :: (a -> [b]) -> [a] -> [b]

なのか。
・・・アカン。do記法ってどうなってるのかわからん。
そこからやるのか・・・。
えーと・・・。

import Control.Monad.List

f1 = do a <- [1,2,3]
        b <- [4,5]
        [(a,b)]

ってあったとして。
>|haskell||
Main> [1,2,3] >>= (\a -> [4,5] >>= (\b -> [(a,b)]))
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
Main> [1,2,3] >>= (\a -> concatMap (\b -> [(a,b)]) [4,5])
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
Main> concatMap (\a -> concatMap (\b -> [(a,b)]) [4,5]) [1,2,3]
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
Main> :l m.hs
[1 of 1] Compiling Main ( m.hs, interpreted )
Ok, modules loaded: Main.
Main> f1
[(1,4),(1,5),(2,4),(2,5),(3,4),(3,5)]
|