[英]Haskell partial application doesn't seem to work with on. Why?
局部使用单个其他函数似乎可以更改所涉及的类型。
从比较长度“ aaa”,“ bb”开始,然后从右侧剥离项目,事情开始时就可以预测:
Prelude Data.Function> :t on compare length "aaa" "bb"
on compare length "aaa" "bb" :: Ordering
Prelude Data.Function> on compare length "aaa" "bb"
GT
Prelude Data.Function> :t on compare length "aaa"
on compare length "aaa" :: [Char] -> Ordering
Prelude Data.Function> let ocla = on compare length "aaa"
Prelude Data.Function> :t ocla
ocla :: [Char] -> Ordering
Prelude Data.Function> ocla "aa"
GT
Prelude Data.Function> :t on compare length
on compare length :: [a] -> [a] -> Ordering
Prelude Data.Function> let ocl = on compare length
Prelude Data.Function> :t ocl
ocl :: [a] -> [a] -> Ordering
Prelude Data.Function> ocl "aaa" "aa"
GT
但是相比之下,我感到惊讶:
Prelude Data.Function> :t on compare
on compare :: Ord b => (a -> b) -> a -> a -> Ordering
Prelude Data.Function> let oc = on compare
Prelude Data.Function> :t oc
oc :: (a -> ()) -> a -> a -> Ordering
Prelude Data.Function> oc length "aaa" "aa"
<interactive>:27:4:
Couldn't match type `Int' with `()'
Expected type: [Char] -> ()
Actual type: [Char] -> Int
In the first argument of `oc', namely `length'
In the expression: oc length "aaa" "aa"
In an equation for `it': it = oc length "aaa" "aa"
为什么oc的类型与on compare的类型不同?
这是由于可怕的单态性限制。 GHCi使用Monomorphism限制来猜测在交互模式下定义的函数或值的最简单类型。 这通常是非常有用的,但是在您确实需要类型类约束类型的地方(例如Ord a => a
()
,它常常是笨拙的()
。 只要为您的oc
函数提供类型签名,就可以了:
let oc :: Ord b => (a -> b) -> a -> a -> Ordering; oc = on compare
如果想使用:set -XNoMonomorphismRestriction
(感谢@Xeo),可以关闭Monomorphism限制,但我建议您反对。 您可以将函数放入文件中并将其加载到GHCi中,或者以交互方式添加类型签名。
维基文章( http://www.haskell.org/haskellwiki/Monomorphism_restriction)更详细地说明了此问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.