我目前需要有點大腦訓練的,我發現這篇文章Haskell and Monads哈斯克爾單子結合討好
我在與運動7再麻煩。隨機函數綁定。
爲了讓問題變得更簡單,我用一個未指定的類型替換了StdGen
類型。因此,而不是...
bind :: (a -> StdGen -> (b,StdGen)) -> (StdGen -> (a,StdGen)) -> (StdGen -> (b,StdGen))
我用...
bind :: (a -> c -> (b,c)) -> (c -> (a,c)) -> (c -> (b,c))
和實際功能impelemtation(剛剛從演習直)
bind f x seed = let (x',seed') = x seed
in f x' seed'
,並隨機2功能試用:
rndf1 :: (Num a, Num b) => a -> b -> (a,b)
rndf1 a s = (a+1,s+1)
rndf2 :: (Num a, Num b) => a -> b -> (a,b)
rndf2 a s = (a+8,s+2)
所以用這個在Haskell編譯器(ghci的),我得到...
:t bind rndf2
bind rndf2 :: (Num a, Num c) => (c -> (a, c)) -> c -> (a, c)
這符合與rndf2
令行禁止作爲第一個參數綁定。
但我不明白的是...
:t bind rndf2 . rndf1
突然給
bind rndf2 . rndf1 :: (Num a, Num c) => a -> c -> (a, c)
這是正確的類型,我們正在努力生產組合物,因爲
bind rndf2 . rndf1
是一個函數,:
- 需要與相同的參數類型
- 並採取從
rndf1
和管道它作爲rndf2
輸入返回到返回相同類型rndf2
rndf1
可以採取2個參數a -> c
和rndf2
返回(a, c)
以便它匹配,這些功能的組合物應該有類型:
bind rndf2 . rndf1 :: (Num a, Num c) => a -> c -> (a, c)
這不符合我最初想出了爲綁定
幼稚型bind f :: (a -> b -> (c, d)) -> (c, d) -> (e, f)
這裏bind
mythically需要一個函數,它有兩個參數,併產生一個函數,一個元組,以使從rndf1
輸出可以爲什麼綁定函數需要被編碼送入rndf2
- 因爲它是
- 爲什麼綁定功能不具有幼稚型
您是什麼意思「我們最終要採用的正確類型」?如果你指的是'unit'的類型,那麼它是錯誤的,因爲'unit :: a - > c - >(a,c)'(注意缺少的'Num'上下文)。 – Vitus
@Vitus - 我已經添加了一些額外的澄清,以說明我在談論的是什麼類型,同時澄清了我的實際問題。 從本質上來說,我的困惑與Chris Bogart從原文的評論[鏈接到這裏]相同(http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html?showComment= 1155160080000#c115516011657470756) – Chime