简体   繁体   English

在Haskell中无法将类型“ a”与“ Int”匹配

[英]Couldn't match type ‘a’ with ‘Int’ in Haskell

place nx is meant to find the place of integer n in the list x , for example place 2 [1,2,3] will return 1 : place nx用于在列表x找到整数n的位置,例如place 2 [1,2,3]将返回1

place :: Int -> [a] -> Int
place n x = length $ takeWhile (/=n) x

But it gets the error Couldn't match type 'a' with 'Int' 但是它得到了错误: Couldn't match type 'a' with 'Int'

Why? 为什么? takeWhile should return a list and its length is an integer, hence place should output an Int eventually. takeWhile应该返回一个列表,它的长度是一个整数,因此place应该最终输出一个Int

The correct type signature for place is: 正确的类型签名place是:

place :: Int -> [Int] -> Int

When you use [a] in place of [Int] you are saying that place will work on a list of any type. 当您使用[a]代替[Int] ,是说该place将适用于任何类型的列表。 For instance, I could call it like this: 例如,我可以这样称呼它:

place 3 [True, False, False, True]

or call it with a list of Char: 或使用Char列表调用它:

place 4 "this is a test"

But neither of these can work because takeWhile will compare each element of the list against the Int n . 但是这些都不行,因为takeWhile会将列表的每个元素与Int n This forces the list to be a list of Ints. 这将强制列表为整数列表。

You are using (/=) :: Eq ty => ty -> ty -> Bool where that second ty ~ Int due to the type of n . 您正在使用(/=) :: Eq ty => ty -> ty -> Bool ,由于n的类型,第二个ty ~ Int If ty is Int then the type of the other argument of (/=) ( x ) must be Int too. 如果tyInt(/=)x )的另一个参数的类型也必须为Int

find the place of integer n in the list x 在列表x找到整数n的位置

ah, but there are no integers in the list at all. 啊,但是列表中根本没有整数。 The type is [a] . 类型是[a] Only if the type were [Int] would it be possible to find an n in it. 仅当类型为[Int] ,才可以在其中找到n

Now, you might say “ [Int] is a possible instantiation of [a] , so it could still work in that case”. 现在,您可能会说“ [Int][a] 的可能实例 ,因此在这种情况下它仍然可以工作”。 Well, it could – but only in that case, and therefore it would be stupid not to enforce a ~ Int in the type signature. 可以,但在那种情况下,因此不强制在类型签名中使用a ~ Int是愚蠢的。

More reasonably, you might want to find any type of number which happens to be equal to the integer n . 更合理地讲,您可能想要找到恰好等于整数n 任何类型的数字 Well, you can do that: 好吧,你可以这样做:

place' :: (Num a, Eq a) => Int -> [a] -> Int
place' n = length . takeWhile (/= fromIntegral n)

Here, I first convert n to the type of number that's contained in the list, and then compare it with those numbers. 在这里,我首先 n 转换为列表中包含的数字的类型,然后将其与这些数字进行比较。

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

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