2014-01-19 28 views
6

我的問題涉及回答另一個問題:https://stackoverflow.com/a/11766789/3212958是否< - 在Haskell do塊中隱式強制類型?

在他的回答,ertes寫入以下類型簽名

select :: [a] -> [(a, [a])] 

然而,當select實際使用,ertes寫入do內的以下阻止

(y, ys) <- select xs 

請幫我流下的元組(y, ys)怎樣的選擇,名字返回類型相匹配的一些光ly [(a, [a])]。 Haskell在某些時候強制類型? (Haskell曾經強制類型?)<-select返回的列表monad中提取類型的元組?

感謝, 最大

---編輯:---

@Lee提醒newbs試圖推理類型的前desugar。在明確了>>=後,更清楚發生了什麼事情。脫糖後,有問題的函數看起來像:

select xs >>= \(y, ys) -> fmap (y:) (perms (n - 1) ys) 

而對於名單,xs >>= f = concat (map f xs)。因此,在這種情況下更好的讀取(y, ys)是作爲映射到列表上的函數的簽名。

+3

'select'返回一個列表。如果你寫'a < - 選擇xs',那麼'a'是'select xs'的每個元素。如果你後來編寫'func a',結果就是在'select xs'的每個元素上應用'func'的結果。這就是列表monad的定義方式。 'a < - 選擇xs; func a'與'select xs >> = func'相同。綁定列表被定義爲:'m >> = f = concat(map f m)',因此您正在編寫'map func(select xs)'。哈斯克爾沒有類型強制。 – user2407038

+0

@ user2407038這裏有一些細微的技術性問題; 「a」不是「每個元素」,「a」表示列表中的一個*(任意但特定)元素。 –

回答

13

do符號,

do x1 <- action1 
    action2 

被翻譯成action1 >>= \x1 -> action2

這意味着如果action1具有用於一些單子m鍵入m a,然後x1具有類型a。這並不是真正的強制類型,而是將單個動作action1的值「拆包」並將其綁定到x1

4

(y, ys)是類型(b, c)

select返回類型是類型[(a, [a])]

的在<-的類型實際上dMonad m => m d的。所以我們可以寫出以下類型的等式:

(b, c) ~ d 
[(a, [a])] ~ Monad m => m d 

解決起來很簡單。首先替代d從第一個方程到第二個公式:

[(a, [a])] ~ Monad m => m (b, c) 

我們看看這是怎麼回事,我將使用[]類型構造的前綴形式(這不是有效的Haskell,但你應該明白我的意思):

[] (a, [a]) ~ Monad m => m (b, c) 

所以

m ~ [] 
(a, [a]) ~ (b, c) 

此時,編譯器會檢查instance Monad [a]存在。其餘的很容易:

a ~ b 
[a] ~ c 
+1

'[](a,[] a)'如果你喜歡,Haskell實際上是有效的,或者甚至是[]((,)a([] a))。 –

+0

哦,我不知道'']'的類型構造函數可以這樣使用,就像值構造函數一樣。 – nponeccop

+0

是的,我也很驚喜地瞭解它。當然可以更容易地解釋列表monad。 –

相關問題