2011-11-21 66 views
1

我試圖按照紙張"Scrap your boilerpolate" Revolutions的程序。 不幸的是,我發現程序中擡起的脊椎視圖部分沒有在我的GHC編譯, 有人可以指出我錯在哪裏?擡起的脊椎視圖

{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, 
    FlexibleInstances, UndecidableInstances, ScopedTypeVariables, 
    NoMonomorphismRestriction, DeriveTraversable, DeriveFoldable, 
    DeriveFunctor, GADTs, KindSignatures, TypeOperators, 
    TemplateHaskell, BangPatterns 
#-} 
{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-name-shadowing 
    -fwarn-monomorphism-restriction -fwarn-hi-shadowing 
    #-} 

module LiftedSpine where 
import Test.HUnit 

-- Lifted Type View 
newtype Id x = InID x 
newtype Char' x = InChar' Char 
newtype Int' x = InInt' Int 
data List' a x = Nil' | Cons' (a x) (List' a x) 
data Pair' a b x = InPair' (a x) (b x) 
data Tree' a x = Empty' | Node' (Tree' a x) (a x) (Tree' a x) 

data Type' :: (* -> *) -> * where 
    Id :: Type' Id 
    Char' :: Type' Char' 
    Int' :: Type' Int' 
    List' :: Type' a -> Type' (List' a) 
    Pair' :: Type' a -> Type' b -> Type' (Pair' a b) 
    Tree' :: Type' a -> Type' (Tree' a) 

infixl 1 :-> 
data Typed' (f :: * -> *) a = (f a) :-> (Type' f) 


size :: forall (f :: * -> *) (a :: *) . Typed' f a -> Int 
size (Nil' :-> (List' a')) = 0 
size (Cons' x xs :-> List' a') = 
    size (xs :-> List' a') + size (x :-> a') 

回答

1

我們必須翻轉(: - >)的兩個字段,即首先必須是 ,註釋的詞必須是第二個。這是因爲在GADT和匹配上匹配的模式 隱含在GHC中從左到右。

1

編制上GHC 6.12.1這個時候我得到的錯誤是:

Couldn't match expected type `f' against inferred type `List' a' 
    `f' is a rigid type variable bound by 
     the type signature for `size' at /tmp/Foo.hs:34:15 
In the pattern: Nil' 
In the pattern: Nil' :-> (List' a') 
In the definition of `size': size (Nil' :-> (List' a')) = 0 

現在看來似乎未能類型的檢查Nil'模式匹配,因爲它沒有意識到,正確的手邊圖案意味着f必須是List'。我懷疑這可能是因爲模式匹配是從左到右完成的,因爲如果我翻轉Typed'的字段順序,以便List a'Nil'之前獲得匹配,它編譯得很好。