Quantified Type

因為compiler的需求
我想寫一個unwrap function可以跟據所傳進來的operator來進行不行的運算
Ex: unwrap (Vint 10) (Vint 20) (>)
unwrap (Vdouble 1.0) (Vdouble 2.0) (==)

code 1:

data Value = Vint Integer | Vdouble Double | Vbool Bool | Vvoid | Uninit
        deriving Show
unwrap :: Ord a => Value -> Value -> (a->a->Bool) -> Bool
unwrap (Vint a) (Vint b) op = op a b
unwrap (Vdouble a) (Vdouble b) op = op a b
unwrap _ _ _ = error "undefined comparison"

但是這會compile不過
IRC上的人跟我說改成這樣,並且還得加上 -fglasgow-exts去compile
因為這不是常用的語法,得用extension

code 2:

unwrap :: Value -> Value -> (forall a. Ord a => a->a->Bool) -> Bool
unwrap (Vint a) (Vint b) op = op a b
unwrap (Vdouble a) (Vdouble b) op = op a b
unwrap _ _ _ = error "undefined comparison"

這兩種type到底差在哪邊呢
首先
unwrap :: Ord a => Value -> Value -> (a->a->Bool) -> Bool

代表說the function can work with any Ord type
這裡的a bound到整個function
也就是說當compile到(Vint a)時
type inference就infer到a為type int
所以後面的double就錯了~
unwrap :: Value -> Value -> (forall a. Ord a => a->a->Bool) -> Bool

則是說 give me an operator which work at every Ord type
這邊的a則只有bound到operator

總結就是forall a要看a所bound的地方是何處
http://cvs.haskell.org/Hugs/pages/users_guide/quantified-types.html

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License