Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 为带十进制的正JSON数编写解析器_Parsing_Haskell - Fatal编程技术网

Parsing 为带十进制的正JSON数编写解析器

Parsing 为带十进制的正JSON数编写解析器,parsing,haskell,Parsing,Haskell,根据Yorgey教授的以下定义: newtype Parser a=Parser{runParser::String->Maybe(a,String)} 以及以下代数数据类型: type Key = String data Json = JObj Key JValue | Arr [JValue] deriving Show data JValue = N Double | S String

根据Yorgey教授的以下定义:

newtype Parser a=Parser{runParser::String->Maybe(a,String)}

以及以下代数数据类型:

type Key = String

data Json = JObj Key JValue 
            | Arr [JValue] 
            deriving Show

data JValue = N Double
              | S String
              | B Bool
              | J Json
               deriving Show
我编写了以下函数来解析带小数点的位置JSON编号:

parseDecimalPoint :: Parser Char
parseDecimalPoint = satisfy (== '.')

type Whole   = Integer
type Decimal = Integer

readWholeAndDecimal :: Whole -> Decimal -> Double
readWholeAndDecimal w d = read $ (show w) ++ "." ++ (show d)

parsePositiveDecimal:: Parser JValue
parsePositiveDecimal = (\x _ y -> f x y) <$> ( 
      (oneOrMore (satisfy isNumber)) <*> parseDecimalPoint <*> 
           (zeroOrMore (satisfy isNumber)) )
  where 
    f x [] = N (read x)
    f x y  = N (-(readWholeAndDecimal (read x) (read y)))
parseDecimalPoint::Parser Char
parseDecimalPoint=满足(='。)
类型整型=整数
类型Decimal=整数
readwholeandecimal::整->十进制->双精度
readwholeandecimal w d=read$(show w)++”+(show d)
parsePositiveDecimal::Parser JValue
parsePositiveDecimal=(\x y->f x y)(
(一个或多个(满足isNumber))解析小数点
(零或更多(满足isNumber)))
哪里
f x[]=N(读取x)
f x y=N(-readwholeandecimal(read x)(read y)))
但是,我得到了以下编译时错误:

JsonParser.hs:30:25:
    Couldn't match expected type ‘t0 -> [Char] -> JValue’
                with actual type ‘JValue’
    The lambda expression ‘\ x _ y -> f x y’ has three arguments,
    but its type ‘String -> JValue’ has only one
    In the first argument of ‘(<$>)’, namely ‘(\ x _ y -> f x y)’
    In the expression:
      (\ x _ y -> f x y)
      <$>
        ((oneOrMore (satisfy isNumber)) <*> parseDecimalPoint
         <*> (zeroOrMore (satisfy isNumber)))

JsonParser.hs:30:49:
    Couldn't match type ‘[Char]’ with ‘Char -> [Char] -> String’
    Expected type: Parser (Char -> [Char] -> String)
      Actual type: Parser [Char]
    In the first argument of ‘(<*>)’, namely
      ‘(oneOrMore (satisfy isNumber))’
    In the first argument of ‘(<*>)’, namely
      ‘(oneOrMore (satisfy isNumber)) <*> parseDecimalPoint’
JsonParser.hs:30:25:
无法匹配预期的类型“t0->[Char]->JValue”
实际类型为“JValue”
lambda表达式“\x\uy->f x y”有三个参数,
但是它的类型'String->JValue'只有一个
在“()”的第一个参数中,即“(\x_'y->fxy)”
在表达式中:
(\x\uy->f x y)
((一个或多个(满足isNumber))解析小数点
(零或更多(满足isNumber)))
JsonParser.hs:30:49:
无法将类型“[Char]”与“Char->[Char]->String”匹配
预期类型:解析器(Char->[Char]->String)
实际类型:解析器[Char]
在“()”的第一个参数中,即
“(一个或多个(满足isNumber))”
在“()”的第一个参数中,即
“(一个或多个(满足isNumber))parseDecimalPoint”
在我的
parsePositiveDecimal
函数中,我对类型的理解是:

(String->Char->String->JValue)(解析器字符串解析器字符串)

我已经学习了一些使用
制作解析器的示例。但我并不是完全在摸索这些类型


如果您能帮助我们理解它们,我们将不胜感激。

仙人掌是正确的。我将在类型上展开一点

::函子f=>(a->b)->fa->fb

我们的
f
这里是
解析器
的第一个参数的类型是
String->Char->String->JValue
。请记住,这可以理解为一个函数,它接受一个
String
,并返回一个函数
Char->String->JValue
,因此
a
类型变量用
String
填充

从中,我们可以看到
的第二个参数需要是
解析器字符串类型
one或more(满足isNumber)
具有该类型

综上所述,我们现在有:

(\x\uy->fxy)(一个或多个(满足isNumber)):解析器(Char->String->JValue)

我们已经从一个包含3个参数的函数(根本不涉及
解析器)转变为一个包含2个参数的函数(包装在
解析器中)。
若要将此函数应用于它的下一个参数
Char
,我们需要:

()::应用程序f=>f(a->b)->f a->f b

f
又是
Parser
,而
a
这里是
Char
parseDecimalPoint::Parser Char
的右侧具有所需的类型

(\x\uy->fxy)(一个或多个(满足isNumber))parseDecimalPoint::Parser(String->JValue)

我们再做一次,以获得:

(\x\uy->fxy)一个或多个(满足isNumber)parseDecimalPoint零个或多个(满足isNumber)::Parser JValue

我利用了知道运算符的优先级和关联性的优势,删除了一些括号。这就是我看到大多数这样的代码编写的方式,但也许Cactus的版本更清楚。甚至全括号版本,强调关联性:

((\x\uy->f x y)
(一个或多个(满足isNumber)))
(小数点)

(zeroOrMore(满足isNumber)):解析器JValue

它应该用括号括起来作为
(\x\uy->f x y)(一个或多个(满足isNumber))parseDecimalPoint(zeroOrMore(满足isNumber)
JsonParser.hs:30:25:
    Couldn't match expected type ‘t0 -> [Char] -> JValue’
                with actual type ‘JValue’
    The lambda expression ‘\ x _ y -> f x y’ has three arguments,
    but its type ‘String -> JValue’ has only one
    In the first argument of ‘(<$>)’, namely ‘(\ x _ y -> f x y)’
    In the expression:
      (\ x _ y -> f x y)
      <$>
        ((oneOrMore (satisfy isNumber)) <*> parseDecimalPoint
         <*> (zeroOrMore (satisfy isNumber)))

JsonParser.hs:30:49:
    Couldn't match type ‘[Char]’ with ‘Char -> [Char] -> String’
    Expected type: Parser (Char -> [Char] -> String)
      Actual type: Parser [Char]
    In the first argument of ‘(<*>)’, namely
      ‘(oneOrMore (satisfy isNumber))’
    In the first argument of ‘(<*>)’, namely
      ‘(oneOrMore (satisfy isNumber)) <*> parseDecimalPoint’