Haskell - foldl $ lambda Set.empty

时间:2014-09-04 03:48:31

标签: haskell lambda

我猜这个例子中存在错误(来自book's chapter)或者我错过了一些内容:

Prelude> let wordSet = foldl (\s e -> Data.Set.insert e s) Data.Set.empty 

然后:

Prelude> wordSet ["blue", "blue", "red", "blue", "red"]

不起作用。它将失败并显示错误:

  

无法匹配预期类型'()'实际类型为“[Char]'

似乎wordSet函数没有任何期望的参数传递?

仍然不明白为什么Data.Set.emptyfoldl的第二个参数但不是第一个。我们如何将内容传递到wordSet

问:它应该如何运作?

1 个答案:

答案 0 :(得分:14)

这是可怕的monomorphism restriction

的另一个案例

有几种方法可以避免这种情况:

添加

let wordSet ws = foldl (\s e -> Data.Set.insert e s) Data.Set.empty ws

禁用限制

> :set -XNoMonomorphismRestriction
> let wordSet = foldl (\s e -> Data.Set.insert e s) Data.Set.empty
> :t wordSet
wordSet :: Ord a => [a] -> containers-0.5.0.0:Data.Set.Base.Set a

在GHCi中添加类型签名(谢谢@Zeta)

let{ wordSet :: Ord e => [e] -> Data.Set.Set e; wordSet = foldl (\s e -> Data.Set.insert e s) Data.Set.empty}

使用并加载源文件(带有类型签名)

module WordSet where

import Data.Set (Set, insert, empty)

wordSet :: (Ord e) => [e] -> Set e
wordSet = foldl (\s e -> insert e s) empty 

使用并加载源文件(禁用限制)

{-# LANGUAGE NoMonomorphismRestriction #-}

module WordSet where

import Data.Set (Set, insert, empty)

wordSet = foldl (\s e -> insert e s) empty 

请注意:这个不是惯用的,因为您应该为您的顶级定义提供签名(GHC很可能会警告您)。