简体   繁体   中英

Haskell: Define product with foldr

I'm trying to define product with foldr :

I could do it with:

new_product xs = foldr (*) 1 xs

but not:

new_product = foldr (*) 1

or:

new_product = \\xs -> foldr (*) 1 xs

Both definition produce the same error:

No instance for (Foldable t0) arising from a use of 'folder'

The type variable 't0' is ambiguous

Relevant bindings include

new_product :: t0 Integer -> Integer

Is it some kind of type error?

How could I fix it?

This is the Monomorphism restriction at work. The solution is to add a type signature:

new_product :: (Foldable t, Num b) => t b -> b
new_product = foldr (*) 1

Essentially, the problem here is that unless you are in GHCi (where this is disabled) Haskell refuses to infer a polymorphic type signature unless you explicitly have variables for the function. As a concrete example:

f x = ...      -- `f` can infer polymorphic type (in `x`) 
f = \x -> ...  -- `f` infers a monomorphic type

In your case, f is new_product and x is xs . When you have the point-free style, Haskell attempts to infer a monomorphic signature for new_product and fails because it can't figure out which Foldable instance to choose (based on foldr ). On the other hand, when you include the xs , Haskell is no longer bound to infer a monomorphic signature, hence everything works.

There is reason to this madness: the point is that when you write something like f = ... it is natural to assume that f only gets evaluated once. Yet, unless we force f to be monomorphic, that isn't necessarily the case.

To use an example related to your function: suppose that I infer that p = num_product [1..1000] has type Num a => a (the most general type in this case), then using p :: Int and p :: Integer will cause us to evaluate p at least twice.

Haskell has therefore decided not to generalize top-level bindings: you only infer polymorphic signatures for functions that have their variables explicit (ie. on the left hand side of the equal). That said, if you wish to explicitly write a polymorphic type signature, you are free to do so.

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