简体   繁体   English

Haskell部分应用程序似乎无法使用。 为什么?

[英]Haskell partial application doesn't seem to work with on. Why?

Partially applying on with a single other function seems to change the types involved. 局部使用单个其他函数似乎可以更改所涉及的类型。

Starting with on compare length "aaa" "bb" and peeling off items from the right, things start off predictable: 从比较长度“ 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

But with on compare I got a surprise: 但是相比之下,我感到惊讶:

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"

Why is the type of oc not the same as the type of on compare? 为什么oc的类型与on compare的类型不同?

This is because of the dreaded Monomorphism restriction. 这是由于可怕的单态性限制。 GHCi uses the Monomorphism restriction to guess the simplest possible type for a function or value defined in interactive mode. GHCi使用Monomorphism限制来猜测在交互模式下定义的函数或值的最简单类型。 This is usually very useful, but quite often it is dumb and picks () where you really want a typeclass restrained type, like Ord a => a . 这通常是非常有用的,但是在您确实需要类型类约束类型的地方(例如Ord a => a () ,它常常是笨拙的() Just provide your oc function a type signature and you'll be fine: 只要为您的oc函数提供类型签名,就可以了:

let oc :: Ord b => (a -> b) -> a -> a -> Ordering; oc = on compare

You can turn off the Monomorphism restriction if you'd like with :set -XNoMonomorphismRestriction (thanks @Xeo), but I would recommend against it. 如果想使用:set -XNoMonomorphismRestriction (感谢@Xeo),可以关闭Monomorphism限制,但我建议您反对。 Either put your functions in a file and load them into GHCi, or add type signatures in interactive mode. 您可以将函数放入文件中并将其加载到GHCi中,或者以交互方式添加类型签名。


The wiki article at http://www.haskell.org/haskellwiki/Monomorphism_restriction explains this problem in more detail. 维基文章( http://www.haskell.org/haskellwiki/Monomorphism_restriction)更详细地说明了此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM