Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: Why does this type-check?

This is a minimal example taken from the Reflection-0.5.

{-# LANGUAGE Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# OPTIONS_GHC -fno-cse -fno-full-laziness -fno-float-in #-}

import Control.Applicative
import Data.Proxy

newtype Zero = Zero Zero deriving (Show)

class ReifiesNum s where
  reflectNum :: Num a => proxy s -> a

instance ReifiesNum Zero where
  reflectNum = pure 0

In GHCi, I get the following:

>:t Zero
Zero :: Zero -> Zero

This makes sense: I'm asking for the type of the constructor which takes a Zero and returns a Zero.

>:t reflectNum
reflectNum :: (ReifiesNum s, Num a) => proxy s -> a

It makes sense that I could write something like

>let x = Just (undefined::Zero)
>reflectNum x

because the type Just Zero matches the type variables 'proxy s'.

Finally, the confusing part:

>:t (reflectNum Zero)
(reflectNum Zero) :: Num a => a

I do not understand how the type of the constructor Zero :: Zero -> Zero apparently matches the type variables 'proxy s', but apparently it does because the type of (reflectNum Zero) is just 'a'.

I'd appreciate help understanding this example, and links to relevant concepts would be greatly appreciated.

Thanks

like image 598
crockeea Avatar asked Jan 23 '12 22:01

crockeea


People also ask

How do you check type of variable in Haskell?

If you are using an interactive Haskell prompt (like GHCi) you can type :t <expression> and that will give you the type of an expression. e.g. or e.g.

What does == mean in Haskell?

The == is an operator for comparing if two things are equal. It is quite normal haskell function with type "Eq a => a -> a -> Bool". The type tells that it works on every type of a value that implements Eq typeclass, so it is kind of overloaded.

Does Haskell check types at runtime?

So no, Haskell types do not exist at runtime, in any form.

What does type do in Haskell?

In Haskell, every statement is considered as a mathematical expression and the category of this expression is called as a Type. You can say that "Type" is the data type of the expression used at compile time.


1 Answers

It's just the infix syntax of the function arrow throwing you off. First, here's an example with an easy-to-understand case: Maybe Int. To make it match proxy s, we just set:

proxy = Maybe
s = Int

Now let's pretend a -> b is instead written Fun a b, and so Zero has type Fun Zero Zero (i.e. (Fun Zero) Zero). To make it match proxy s, we set:

proxy = Fun Zero
s = Zero

In reality, proxy is (->) Zero, and so proxy s is ((->) Zero) Zero(->) Zero ZeroZero -> Zero.

like image 72
ehird Avatar answered Sep 20 '22 21:09

ehird