简体   繁体   中英

What is '(Floating a, Num (a -> a))' in Haskell?

In Haskell, I just know that

:type ((+)(1))
((+)(1)) :: Num a => a -> a
((+)(1) 2
3

But how about

:type abs(sqrt)
abs(sqrt) :: (Floating a, Num (a -> a)) => a -> a

Actually, I try many times but fail to use the function 'abs(sqrt)'. Then I have a few questions. What is the type(class?) '(Floating a, Num (a -> a))'? Is it possible to use the function 'abs(sqrt)'? How?

When you see Num (a -> a) it generally means you made a mistake somewhere.

Perhaps you really wanted: abs . sqrt abs . sqrt which has type Floating c => c -> c - ie it's a function of a Floating type (eg Float, Double) to the same Floating type.

It is probably not possible to use this function.

What's likely happening here is that the type is saying that abs(sqrt) has the constraints that a must be of type class Floating and (a -> a) must be of type class Num . In other words, the sqrt function needs to be able to be treated as if it was a number.

Unfortunately, sqrt is not of type class Num so there won't be any input that will work here (not that it would make sense anyway). However, some versions of GHCi allow you to get the type of as if it were possible.

Have a look at Haskell type length + 1 for a similar type problem.

As ErikR has said, perhaps you meant to write abs . sqrt abs . sqrt instead.

A type class is a way to generalize functions so that they can be polymorphic and others can implement those functions for their own types. Take as an example the type class Show , which in a simplified form looks like

class Show a where
    show :: a -> String

This says that any type that implements the Show typeclass can be converted to a String (there's some more complication for more realistic constraints, but the point of having Show is to be able to convert values to String s).

In this case, the function show has the full type Show a => a -> String .

If we examine the function sqrt , its type is

> :type sqrt
sqrt :: Floating a => a -> a

And for abs :

> :type abs
abs :: Num b => b -> b

If you ask GHCi what the types are it will use the type variable a in both cases, but I've used b in the type signature for abs to make it clear that these are different type variables of the same name, and it will help avoid confusion in the next step.

These type signatures mean that sqrt takes a value whose type implements the Floating typeclass (use :info Floating to see all the members) and returns a value of that same type, and that the abs function takes a value whose type implements the Num typeclass and returns a value of that same type.

The expression abs(show) is equivalently parsed as abs sqrt , meaning that sqrt is the first and only argument passed to abs . However, we just said that abs takes a value of a Num type, but sqrt is a function, not a number. Why does Haskell accept this instead of complaining? The reason can be seen a little more clearly when we perform substitution with the type signatures. Since sqrt 's type is Floating a => a -> a , this must match the argument b in abs 's type signature, so by substituting b with Floating a => a -> a we get that abs sqrt :: (Floating a, Num (a -> a)) => a -> a .

Haskell actually allows the function type to implement the Num typeclass, you could do it yourself although it would likely be nonsensical. However, just because something wouldn't seem to make sense to GHC, so long as the types can be cleanly solved it will allow it.

You can't really use this function, it just doesn't really make sense. There is no built-in instance of Num (a -> a) for any a , so you'd have to define your own. You can, however, compose the functions abs and sqrt using the composition operator . :

> :type abs . sqrt
abs . sqrt :: Floating c => c -> c

And this does make sense. This function is equivalent to

myfunc x = abs (sqrt x)

Note here that x is first applied to sqrt , and then the result of that computation is passed to abs , rather than passing the function sqrt to abs .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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