问题
{- 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)
This is my Haskell Project.
I have been trying it for 4 days.
I just wanna verify whether my LExpTree
data is correct?
I don't think so though..
After that, I have to create a series of parsers as grammar
This is 3 of them.
{-
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); }
And I am getting these errors.
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.
The project is to create Łukasiewicz expressions C for certain, U for uncertain and I for impossible.
And I already have a Parser.hs loaded and it has all the Parser and parse types and its associated functions.
I understand this is a school project and supposed to try it my best. I still have 2 more parts and this is supposed to be an easy part.
I would appreciate if someone can help me.
Thanks.
回答1:
The main problem is that the LExpTree
type needs an additional type parameter to become a concrete type. This is, I believe, is a correct version of lukVar
:
lukVar :: Parser (LExpTree a)
lukVar = do i <- ident; return (V i)
-- alternatively: V <$> ident
Note that this is a parser for LExpTree a
for any type a
.
Now in lukLit
you are trying to return things like L C
. I don't see where C
is defined, but let's suppose that the type of C
is MyLits
. Then the signature of lukLit
is:
lukLit :: Parser (LExpTree MyLits)
Evidently the type parameter a
in LExpTree a
is the type of the literals you want to use.
Note the difference between lukVar
and lukLit
- your code for lukVar
will work with any literal type hence the variable a
in the type signature. The code for lukLit
returns literals from MyLits
and thus returns a LExpTree MyLits
.
Now you should be able to fix up lukExp
. My guess is that it will have the signature
lukExp :: Parser (LExpTree a)
I bet you can just remove the type signatures and let GHC infer them. In these cases having incorrect type signatures is causing the errors.
来源:https://stackoverflow.com/questions/37100836/haskell-creating-new-data