开发者

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

开发者 https://www.devze.com 2023-01-06 17:43 出处:网络
Apparently, my type signature was off. I\'ve since found out why. Now, I\'m interested in knowing mor开发者_运维技巧e about the GHCI inferred signature on my typo. I was trying to get this code to wor

Apparently, my type signature was off. I've since found out why. Now, I'm interested in knowing mor开发者_运维技巧e 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
0

精彩评论

暂无评论...
验证码 换一张
取 消