Поднятый позвоночник - PullRequest
       23

Поднятый позвоночник

1 голос
/ 21 ноября 2011

Я пытался следовать программе работы «Отбрось свой котел» Революции . К сожалению, я обнаружил, что программа в поднятом виде позвоночника не компилируется в моем 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' )

Ответы [ 2 ]

1 голос
/ 21 ноября 2011

мы должны поменять два поля (: ->), то есть тип должен быть первый и аннотированный термин должен быть вторым. Это потому что шаблон соответствие в GADT и уточнение неявно слева направо в GHC.

1 голос
/ 21 ноября 2011

Я получаю ошибку при компиляции на 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', он компилируется просто отлично.

...