Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
842 views
in Technique[技术] by (71.8m points)

haskell - What is going on with the types in this ghci session?

I'm learning Haskell, and I was playing around in ghci when I came across something very puzzling.

First, create a simple add function:

Prelude> let add x y = x + y

Note that it works with ints and floats:

Prelude> add 3 4
7
Prelude> add 2.5 1.3
3.8

Now create an apply function. It's identical to $ (but not infix). It works like a no-op on add:

Prelude> let apply f x = f x
Prelude> apply add 3 4
7
Prelude> apply add 2.5 1.3
3.8

Ok, now make add' which is the same as add' but using apply:

Prelude> let add' = apply add
Prelude> add' 3 4
7
Prelude> add' 2.5 1.3

<interactive>:1:9:
    No instance for (Fractional Integer)
      arising from the literal `1.3' at <interactive>:1:9-11
    Possible fix: add an instance declaration for (Fractional Integer)
    In the second argument of `add'', namely `1.3'
    In the expression: add' 2.5 1.3
    In the definition of `it': it = add' 2.5 1.3

Wat.

Here are the types:

Prelude> :t add
add :: (Num a) => a -> a -> a
Prelude> :t apply add
apply add :: (Num t) => t -> t -> t
Prelude> :t add'
add' :: Integer -> Integer -> Integer
Prelude> 

Why does add' have a different type than apply add?

Is this a ghci oddity, or is this true in Haskell in general? (And how can I tell the difference?)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It's the Monomorphism restriction. When you define a value with a simple pattern binding (just the name, without any function arguments) and without a type signature, it gets a monomorphic type. Any type variables are tried to be disambiguated according to the defaulting rules, if that doesn't succeed you get a type error.

In this case, the Num constrained type variable gets defaulted to Integer.

You can turn off the monomorphism restriction with

ghci> :set -XNoMonomorphismRestriction

or with the -XnoMonomorphismRestriction flag on the command line.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...