在什么情况下可以通过
定义函数f :: a -> b -> c -> d
f w x y z = ...
我不会想到这可能,但在查看我发现的enumerator
包时:
enumFileRange :: FilePath
-> Maybe Integer -- ^ Offset
-> Maybe Integer -- ^ Maximum count
-> Enumerator B.ByteString IO b
enumFileRange path offset count step = do
h <- tryIO (IO.openBinaryFile path IO.ReadMode)
let iter = enumHandleRange 4096 offset count h step
Iteratee (Exc.finally (runIteratee iter) (IO.hClose h))
显然我们有三个参数的函数,通过传入四个参数来实现。同样,enumHandleRange
的签名是
enumHandleRange :: MonadIO m
=> Integer -- ^ Buffer size
-> Maybe Integer -- ^ Offset
-> Maybe Integer -- ^ Maximum count
-> IO.Handle
-> Enumerator B.ByteString m b
表示它有四个参数,但是我们通过传入五个参数enumFileRange
在let iter = enumHandleRange 4096 offset count h step
中调用它。
有人知道这是如何工作的,以及一般性如何?
答案 0 :(得分:12)
Enumerator
是函数类型的类型同义词(类似于C中的typedef
):
type Enumerator a m b = Step a m b -> Iteratee a m b
所以enumFileRange
实际上有以下类型:
enumFileRange :: FilePath
-> Maybe Integer -- ^ Offset
-> Maybe Integer -- ^ Maximum count
-> Step B.ByteString IO b
-> Iteratee B.ByteString IO b
答案 1 :(得分:1)
Haskell中的所有函数都有a -> b
形式的签名。如果函数具有“多个参数”,则这仅仅意味着b
恰好是函数类型。所以,回答
在什么情况下函数f :: a - &gt; b - &gt; c - &gt; d由
定义f w x y z = ...
答案将始终,因为像a, b, c, d
这样的无约束类型变量总是可以解析为函数类型。实际上,即使类型类约束与函数“明显不兼容”,类型检查器也会首先假设这一点,这就是为什么我们有时会得到如此有趣的错误消息,如
GHCi,版本7.6.2:http://www.haskell.org/ghc/ :?寻求帮助
加载包ghc-prim ...链接...完成。
加载包integer-gmp ...链接...完成。
加载包基...链接...完成。
前奏&GT; 7“x”
&LT;互动&GT;:2:1:
没有(Num([Char] - > t0))的实例来自文字“7” 可能的解决方法:为(Num([Char] - &gt; t0))添加实例声明 在表达式中:7
在表达式中:7“x”
在'it'的等式中:it = 7“x”
对于Enumerator B.ByteString IO b
等固定类型,这不是真的。在这种情况下,你是否真的有必要处理一个函数类型的typedef,就像Enumerator
所说的rightfold一样。