What does has kind 'Constraint' mean in Haskell

前端 未结 2 649
孤街浪徒
孤街浪徒 2021-02-15 15:16

I am fresh to Haskell and I am trying to understand the language by writing some code. I am only familiar with very simple instructions on ghci: head, tail, sum, (*), and the li

2条回答
  •  暗喜
    暗喜 (楼主)
    2021-02-15 15:31

    A few things to adjust:

    0) mod isn't a good name for your function, as it is the name of the modulo function from the standard library. I will call it norm instead.

    1) The type signature you meant to write is:

    norm :: Num a => [a] -> a
    

    [a] is the type of a list with elements of type a. The Num a before the => isn't a type, but a constraint, which specifies that a must be a number type (or, more accurately, that it has to be an instance of the Num class). [Num a] => leads to the error you have seen because, given the square brackets, the type checker takes it as an attempt to use a list type instead of a constraint.

    Beyond the Num a issue, you have left out the result type from the signature. The corrected signature reflects that your function takes a list of numbers and returns a number.

    2) The Num a constraint is too weak for what you are trying to do. In order to use sqrt, you need to have not merely a number type, but one that is an instance of Floating (cf. leftaroundabout's comment to this answer):

    GHCi> :t sqrt
    sqrt :: Floating a => a -> a
    

    Therefore, your signature should be

    norm :: Floating a => [a] -> a
    

    3) [x] is a list with a single element, x. If your argument is already a list, as the type signature says, there is no need to enclose it in square brackets. Your function, then, becomes:

    norm :: Floating a => [a] -> a
    norm x = sqrt a
        where a = sum b
                where b = map sq x
    

    Or, more neatly, without the second where-block:

    norm :: Floating a => [a] -> a
    norm x = sqrt (sum b)
        where b = map sq x
    

提交回复
热议问题