Haskell创建新数据

时间:2016-05-08 14:20:11

标签: haskell functional-programming expression-trees

{- P A R T 2 : Implementation of a parser for Łukasiewicz expressions
--TODO Define the type LExpTree, using the constructors L, V, N, Q, S, K, A, O, E, I
L for Lukasiewicz literals (i.e. C, I or U)
V for Variables (string) 
N for a node representing the prefix neg
Q for a node representing the prefix pos
S for a node representing the prefix cer
K for a node representing the prefix unk
A for a node representing the infix And
O for a node representing the infix Or
E for a node representing the infix Equivalence
M for a node representing the infix Implication
It will be convenient to have the new type derive from the classes Show and Eq
-}
data LExpTree a = L a
                | V [Char]
                | N (LExpTree a)
                | Q (LExpTree a)
                | S (LExpTree a)
                | K (LExpTree a)
                | A (LExpTree a) (LExpTree a)
                | O (LExpTree a) (LExpTree a)
                | E (LExpTree a) (LExpTree a)
                | M (LExpTree a) (LExpTree a)
                deriving (Show, Eq)

这是我的Haskell项目。 我已经尝试了4天。 我只是想验证我的LExpTree数据是否正确?

我不这么认为..

之后,我必须创建一系列解析器作为语法

这是其中的3个。

{- 
lukExp :: lukOpd ( '<->' lukExp | '-->' lukExp| e )
lukVar :: lowercase (Alphanumeric)*
lukLit :: C | I | U
-}
lukExp :: Parser LExpTree
lukExp = do o <- lukOpd
            ( do { symbol "<->";
                   e <- lukExp;
                   return (E (o <-> e)); }
             +++ do { symbol "-->";
                      e <- lukExp;
                      return (E (o --> e)); }
             +++ return (E o) )

lukVar :: Parser LExpTree 
lukVar = ident

lukLit :: Parser LExpTree
lukLit = do { symbol "C";
              return (L C); }
         +++ do { symbol "I";
                  return (L I); }
         +++ do { symbol "U";
                  return (L U); }

我收到了这些错误。

proj.hs:131:18:
    Expecting one more argument to `LExpTree'
    The first argument of `Parser' should have kind `*',
      but `LExpTree' has kind `* -> *'
    In the type signature for `lukExp': lukExp :: Parser LExpTree

proj.hs:184:18:
    Expecting one more argument to `LExpTree'
    The first argument of `Parser' should have kind `*',
      but `LExpTree' has kind `* -> *'
    In the type signature for `lukVar': lukVar :: Parser LExpTree

proj.hs:187:18:
    Expecting one more argument to `LExpTree'
    The first argument of `Parser' should have kind `*',
      but `LExpTree' has kind `* -> *'
    In the type signature for `lukLit': lukLit :: Parser LExpTree
Failed, modules loaded: Parser.

该项目是为某些创造Łukasiewicz表达式C,U为不确定因素而我是不可能的。

我已经加载了Parser.hs,它具有所有Parser和parse类型及其相关函数。

我知道这是一个学校项目,应该尽我所能。我还有2个零件,这应该是一个简单的部分。

如果有人可以帮助我,我将不胜感激。

感谢。

1 个答案:

答案 0 :(得分:3)

主要问题是LExpTree类型需要一个额外的类型参数才能成为具体类型。我相信这是lukVar的正确版本:

lukVar :: Parser (LExpTree a)
lukVar = do i <- ident; return (V i)
         -- alternatively: V <$> ident

请注意,对于任何类型LExpTree a,这都是a的解析器。

现在在lukLit,您正在尝试返回L C之类的内容。我不知道C的定义位置,但我们假设C的类型为MyLits。然后lukLit的签名是:

lukLit :: Parser (LExpTree MyLits)

显然a中的类型参数LExpTree a是您要使用的文字类型。

请注意lukVarlukLit之间的区别 - 您的lukVar代码将适用于任何文字类型,因此类型签名中的变量alukLit的代码会从MyLits返回文字,从而返回LExpTree MyLits

现在您应该可以修复lukExp了。我的猜测是它会有签名

lukExp :: Parser (LExpTree a)

我打赌你可以删除类型签名并让GHC推断它们。在这些情况下,类型签名不正确会导致错误。