【问题标题】:Change variable type to match the expected type更改变量类型以匹配预期类型
【发布时间】:2019-03-14 16:08:35
【问题描述】:

在下面的代码中,我得到了错误

无法将“Integer”类型与“Int”匹配
预期类型:[(Test, [Test])]
实际类型:[(Integer, [Integer])]

执行时

testFunc test

以下声明

type TestType = Int
a = [(1,[2,3])]

testFunc :: [(TestType ,[TestType])] -> TestType 
testFunc ((a,(b:c)):d) = a

如何声明我的列表 a 以使其与 testFunc 的类型匹配?

有没有办法在不修改type Test = Inta的声明的情况下修复错误?

【问题讨论】:

标签: haskell types type-mismatch


【解决方案1】:

如何声明我的列表“test”以匹配 testFunc 的类型?

好吧,通过将 this 声明为类型。

a :: [(TestType, [TestType])]
a = [(1,[2,3])]

一般来说,您应该始终为这样的顶级定义提供显式类型签名。如果没有这样的签名,编译器会为您选择一个。一般来说,Haskell 会尽量选择最通用的可用类型;在这种情况下,那将是

a :: (Num a, Num b) => [(a, [b])]

...这将包括[(Int, [Int])][(Integer, [Integer])]。但是,monomorphism restriction 默认限制类型,不包括这种多态性。所以GHC要选择一个版本,默认是Integer,不是Int

再次,正确的解决方案是提供显式签名。不过,你也可以关闭单态限制:

{-# LANGUAGE NoMonomorphismRestriction #-}

type TestType = Int
a = [(1,[2,3])]

testFunc :: [(TestType ,[TestType])] -> TestType 
testFunc ((x,(y:z)):w) = x

main :: IO ()
main = print $ testFunc a

【讨论】:

  • {-# LANGUAGE NoMonomorphismRestriction #-} 在上一个示例中不是必需的;没有它,相同的代码也可以正常工作。当您在定义a 的同一源文件中调用testFunc a 时,单态限制会推断出a :: [(TestType, [TestType])]。如果唯一使用站点需要Int,则单态限制不会选择Integer 而不是Int,如您的示例所示。我怀疑 OP 在加载包含 testFunca 的文件后调用 GHCi 中的函数。
  • @Ben 很有趣,我实际上不知道它会在顶级绑定上做到这一点。不过,这不是我所依赖的——将该定义移至另一个模块会改变类型推断!最好总是签名。
  • 我绝对同意正确的解决方案是给出类型签名。
猜你喜欢
  • 2019-08-10
  • 2016-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多