有没有办法让这个教会编码的程序编译?

时间:2016-02-04 02:28:34

标签: haskell types

{-# LANGUAGE RankNTypes, ScopedTypeVariables, NoMonomorphismRestriction #-}

type CList a = (forall t . (a -> t -> t) -> t -> t)

ccons :: forall a . a -> CList a -> CList a
ccons h t = (\ c n -> c h (t c n))

cnil :: forall h . CList h
cnil = (\ c n -> n)

cToList :: forall a . CList a -> [a]
cToList list = list (:) []

cFromList :: forall a . [a] -> CList a
cFromList = foldr ccons cnil

main = print (cToList (cFromList [1,2,3]))

我理解它没有编译的原因与forallccons的使用有关。注释ccons类型将使其编译,但ccons的类型很尴尬。解决问题的正确方法是什么?

test.hs:15:23:
    Couldn't match type ‘(a -> t -> t) -> t -> t’
                   with ‘forall t1. (a -> t1 -> t1) -> t1 -> t1’
    Expected type: a
                   -> ((a -> t -> t) -> t -> t) -> (a -> t -> t) -> t -> t
      Actual type: a -> CList a -> (a -> t -> t) -> t -> t
    Relevant bindings include
      cFromList :: [a] -> CList a (bound at test.hs:15:5)
    In the first argument of ‘foldr’, namely ‘ccons’
    In the expression: foldr ccons cnil

2 个答案:

答案 0 :(得分:3)

你为什么要使用cconscFromList只是翻转foldr

cFromList ::  [a] -> CList a
cFromList xs op seed = foldr op seed xs

答案 1 :(得分:2)

正如@Daniel Wagner指出的那样,仅仅使用newtype代替type解决了这个问题:

newtype CList a = CList { runCList :: (forall t . (a -> t -> t) -> t -> t) }

ccons :: forall h . h -> CList h -> CList h
ccons h t = CList (\ c n -> c h (runCList t c n))

cnil :: forall h . CList h
cnil = CList (\ c n -> n)

cToList :: forall a . CList a -> [a]
cToList list = runCList list (:) []

cFromList :: forall a . [a] -> CList a
cFromList list = (foldr ccons cnil list)

main = print (cToList (cFromList [1,2,3]))

显然我之前也被告知过,但我真的不记得也没找到问题。对不起伙计们:(