【问题标题】:Functions with type signature Integer/Int: "type Integer does not match Int"具有类型签名 Integer/Int 的函数:“类型 Integer 与 Int 不匹配”
【发布时间】:2011-12-19 22:47:02
【问题描述】:

对于

x :: Integer -> [a] -> [a]
x = take

y :: Integer -> [a] -> [a]
y _ [] = []
y n xs = take n xs

Hugs 和 GHC 都报告类型错误:

ERROR "test.hs":5 - Type error in application
*** Expression     : take n xs
*** Term           : n
*** Type           : Integer
*** Does not match : Int

ERROR "test.hs":8 - Type error in explicitly typed binding
*** Term           : x
*** Type           : Int -> [a] -> [a]
*** Does not match : Integer -> [a] -> [a]

这是因为“take”的签名是“Int -> ...”。有没有办法告诉类型系统直接将 Integer 转换为 Int(不使用 fromIntegral),或者最好(保持 Integer 的非约束大小)“构造”一个​​版本的 take(或任何其他显式使用 Int 的函数) 对于整数?还是我必须编写自己的 Prelude-Functions 版本?目前,我的代码要么充斥着 fromIntegral(如果 Integer 大小超过 Int 的维度,则不会运行),或者是对标准函数进行了简单的重新实现,感觉非常笨拙。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    请改用来自 Data.List 的 genericTake。 “通用”列表函数接收 Integer 而不是 Int。

    以后,如果你想通过类型签名搜索 Haskell 函数,你可以使用Hoogle


    在更一般的意义上,如果您只想添加一个转换步骤,您可以使用内置的组合运算符轻松创建您自己的函数。

    --explicit type signature to force the less general types...
    integerToInt :: Integer -> Int
    integerToInt = fromIntegral
    
    myGenericTake = take . integerToInt
    
    --You can now use myGenericTake throughout the code.
    

    【讨论】:

    • take 只是一个例子。我仍在学习 Haskell,我试图通过自己捣乱来补充我在大学所受的微薄教育,这就是我偶然发现的原因。如果我想将任何 x :: Int -> ... 与整数一起使用,那是不可能的吗? (或仅使用 fromIntegral?)
    • @Max:添加了一点关于函数组合的内容。
    • 谢谢。最后一个问题:我能以任何方式告诉 Haskell,我希望它在遇到特定类型时使用我的 Prelude 函数(或任何函数)的实现吗?我想写一个带有签名的函数“take”(例如) take :: Integer -> ... 然后让 Haskell 在适当的时候选择它,这样我就可以使用标准名称而不是“myTake”或在我的代码中“取 .fromIntegral”。
    • Haskell 不支持那种 C++ 风格的重载,因为它会弄乱类型推断。能够为两个不同的函数赋予相同名称的唯一方法是使用类型类。如果你看一下 genericTake 的类型签名(`Integral i => i -> [a] -> [a])就是那个重载版本。
    • 您还可以导入 Prelude 隐藏原始片段,以便您可以将名称用于您自己的另一个功能。但是,我不建议这样做。
    【解决方案2】:

    Haskell 采用 not 制作 any 隐式强制转换的方法。因此,当您遇到take 之类的函数时,您只需需要 使用fromIntegral 或类似方法执行显式转换。

    如果这让您感到困扰,请发表您对改进 Prelude 的看法。您当然不会孤单地希望改进 Prelude 功能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      相关资源
      最近更新 更多