gpt4 book ai didi

haskell - 为什么积分约束在调用长度时需要 fromIntegral ?

转载 作者:行者123 更新时间:2023-12-01 17:11:33 24 4
gpt4 key购买 nike

我刚刚开始用 Haskell 编程,我正在解决 99 Haskell problems ,当我快完成第 10 个时,我遇到了这个问题:

-- Exercise 9
pack :: Eq a => [a] -> [[a]]
pack [] = []
pack list = let (left,right) = span (== head list) list in
left : pack right

-- Exercise 10
encode :: (Eq a, Integral c) => [a] -> [(c, a)]
encode [] = []
encode list = map (\x -> (length x, head x)) (pack list)
-- this doesn't work ^^^^^^^^

产生的错误告诉我

Could not deduce (c ~ Int)
from the context (Eq a, Integral c)
bound by the type signature for
encode :: (Eq a, Integral c) => [a] -> [(c, a)]
at C:\fakepath\ex.hs:6:11-47
`c' is a rigid type variable bound by
the type signature for
encode :: (Eq a, Integral c) => [a] -> [(c, a)]
at C:\fakepath\ex.hs:6:11
In the return type of a call of `length'
In the expression: length x
In the expression: (length x, head x)

我已经通过插入我在Learn you a Haskell中读到的函数来解决这个问题。 :fromIntegral

encode list = map (\x -> (fromIntegral $ length x, head x)) (pack list)

所以,我的问题是,为什么需要这样做

我运行了 :t length 并得到了 [a] -> Int,这对我来说是一个定义良好的类型,它应该满足 Integral c 约束。

最佳答案

类型签名 (Eq a, Integral c) => [a] -> [(c, a)] 表示该函数适用于任何类型ac 在适当的类型类中。实际使用的类型在调用站点指定。

作为一个简单的例子,我们看一下空列表的类型:

:t []
[a]

这意味着[]表示String的空列表,以及Int的空列表,空的列表>也许 [也许 Bool] 以及您能想象到的任何其他类型。我们可以想象将其包装在一个普通的标识符中:

empty :: [a]
empty = []

empty 显然与 [] 的工作方式相同。所以你可以看到下面的定义是没有意义的:

empty :: [a]
empty = [True]

毕竟,[True] 永远不可能是 [Int][String] 或您想要的任何其他空列表。

这里的想法是相同的,只是我们对变量也有类型类约束。例如,您可以使用 encode 返回 [(Integer, String)] 列表,因为 Integer 也在 Integral 类。

所以你必须返回一些多态的东西,可以是任何Integral——就像fromIntegral所做的那样。如果您刚刚返回 Int,则 encode 只能用作 Int,而不能用作任何 Integral

关于haskell - 为什么积分约束在调用长度时需要 fromIntegral ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18061649/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com