当前位置: 动力学知识库 > 问答 > 编程问答 >

types - Haskell: What is the differrence between `Num [a] => a` and `Num a => [a]`

问题描述:

Apparently, my type signature was off. I've since found out why. Now, I'm interested in knowing more about the GHCI inferred signature on my typo. I was trying to get this code to work:

elemNum :: (Eq a, Num b) => a -> [a] -> b

elemNum e l = f e l

where f _ [] = [] -- this was my typo, supposed to read 0

f e (x:xs)

| x == e = 1 + f e xs

| otherwise = f e xs

It obviously doesn't work for the reason noted above; but, if I remove my signature it compiles (not sure why, please explain), and I get this signature:

elemNum :: (Num [a], Eq t) => t -> [t] -> [a]

I've never seen the typeclass Num [a] before.. What does that mean, and how does it compare to (Num a) => [a].

网友答案:

Num a means that the type a can be treated as a number; eg. you can add two as together to get a new a or you can negate an a and get an a. Integer and Double fall into this category.

Correspondingly, Num [a] means that the type [a] can be treated as a number. I.e. you can add together two lists of a to get a new list of a. This is very unlikely to be meaningful because no lists are numbers (by default). It means that you are treating a list like it is a number, causing GHC to conclude that you must want your list to act like a number, and thus adding an appropriate constraint.

Such a constraint might arise from a function like:

foo (x:xs) = xs + 1

xs is pattern matched as the tail of a list, and thus is itself a list, and then you are adding to it, treating the list as a number.

网友答案:

Num [a] constraint means that list is instance of Num type class.

foo :: Num a => [a]

is list of values which are instances of Num type class

bar :: Num [a] => [a]

is list of values which is instance of Num type class by itself. This means that you can use all functions from Num and construct lists from numeric literals so following code is valid although requires FlexibleContexts

bar :: Num [a] => [a]
bar = 42

P.S. You don't need helper function here. elemNum e l = f e l ⇒ elemNum = f. So you can write your function as

elemNum _ [] = 0
elemNum e (x:xs)
  | x == e = 1 + f e xs
  | otherwise = f e xs
分享给朋友:
您可能感兴趣的文章:
随机阅读: