【问题标题】:Haskell partial application doesn't seem to work with on. Why?Haskell 部分应用程序似乎无法使用。为什么?
【发布时间】:2014-04-08 16:30:42
【问题描述】:

部分应用单个其他函数似乎会改变所涉及的类型。

从比较长度“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的类型不一样?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这是因为可怕的单态限制。 GHCi 使用单态限制来猜测在交互模式中定义的函数或值的最简单的可能类型。这通常非常有用,但通常它是愚蠢的并选择(),你真的需要一个类型类约束类型,比如Ord a =&gt; a。只需为您的 oc 函数提供类型签名即可:

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

    如果您愿意,可以使用 :set -XNoMonomorphismRestriction 关闭单态限制(感谢 @Xeo),但我建议您不要这样做。要么将你的函数放在一个文件中并将它们加载到 GHCi 中,要么在交互模式下添加类型签名。


    http://www.haskell.org/haskellwiki/Monomorphism_restriction 的 wiki 文章更详细地解释了这个问题。

    【讨论】:

    • 或使用:set -XNoMonomorphismRestriction 获取 GHCi。
    • 准确的说是结合ExtendedDefaultRules的单态限制。前者强制使用单态类型。后者导致 GHCi 选择 () 而不是报告错误。
    • @kosmikus TIL。下次出现这个问题时,我一定会提到。
    • 这就是为什么 GHCi 7.8 默认情况下仍然有 -XNoMonomorphismRestriction iirc
    • 你为什么反对它? NoMonomorphismRestriction 在源文件中没有太多理由,因为顶级类型签名通常足以解决由单态限制引起的任何问题,但是在 GHCi 中使用它并没有真正的危害(至少没有将证明在执行您建议的操作时会出现的每个声明的额外开销是合理的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多