
Am Samstag 01 August 2009 19:44:49 schrieb Michael P Mossey:
I was playing around with type constructors and I wrote this:
data Foo a b = Foo1 [a]
| Foo2 (a -> b)
t3 = Foo1 [1, 2, 3]
I wanted to see what ghci thought the type of t3 was. Essentially, it's data that doesn't use all of the type variables. So this ran fine, and
*Main> :t t3 t3 :: Foo Integer b
Actually, the type of t3 could be t3 :: Num a => Foo a b but without a type signature the monomorphism restriction applies and a is defaulted to Integer. *MFoo> :t Foo2 even Foo2 even :: (Integral a) => Foo a Bool
Wow! The data exists but it doesn't have a "complete type" so to speak.
It does, it has a polymorphic type, or one could say it has many types: *MFoo> :t [t3,Foo2 even] [t3,Foo2 even] :: [Foo Integer Bool] *MFoo> :t [t3,Foo2 id] [t3,Foo2 id] :: [Foo Integer Integer] *MFoo> :t (t3 :: Foo Integer Bool) (t3 :: Foo Integer Bool) :: Foo Integer Bool *MFoo> :t (t3 :: Foo Integer Char) (t3 :: Foo Integer Char) :: Foo Integer Char *MFoo> :t (t3 `asTypeOf` (Foo2 even)) (t3 `asTypeOf` (Foo2 even)) :: Foo Integer Bool *MFoo> :t (t3 `asTypeOf` (Foo2 id)) (t3 `asTypeOf` (Foo2 id)) :: Foo Integer Integer
This worked, too:
f3 (Foo1 xs) = length xs
*Main> f3 t3 3
*MFoo> :t (\(Foo1 xs) -> length xs) (\(Foo1 xs) -> length xs) :: Foo t1 t -> Int
This is surprising to a conventional programmer. But does this naturally relate to other features of Haskell. Perhaps laziness? (I.e. data of type Foo doesn't always need a type b so it just doesn't have one until it needs one.)
Polymorphism and type inference, not laziness.
Thanks, Mike