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
Haskell 如何创建新类型的解析器?_Haskell_Newtype - Fatal编程技术网

Haskell 如何创建新类型的解析器?

Haskell 如何创建新类型的解析器?,haskell,newtype,Haskell,Newtype,我想创建一个新类型的解析器,看看它是什么样子 我试过了 newtype Parser a = PsrOf{ -- | Function from input string to: -- -- * Nothing, if failure (syntax error); -- * Just (unconsumed input, answer), if success. dePsr :: String -> Maybe (String, a)}

我想创建一个新类型的解析器,看看它是什么样子

我试过了

newtype Parser a = PsrOf{
    -- | Function from input string to:
    --
    --   * Nothing, if failure (syntax error);
    --   * Just (unconsumed input, answer), if success.
    dePsr :: String -> Maybe (String, a)}
但它出现了一个错误

*ParserLib> PsrOf{"hello"}
:5:7:错误:分析输入“”时出错

您已经创建了类型。现在您想创建该类型的值。为此,您需要使用类型为
String->Maybe(String,a)
的值调用
PsrOf
。例如:

<interactive>:5:7: error: parse error on input ‘"’
要实际使用解析器,需要先提取函数,然后再将其应用于字符串:

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

get3 :: String -> Maybe (String, Int)
get3 ('3':xs) = Just (xs, 3)
get3 _ = Nothing  -- Any string, including the empty string, that doesn't start with '3'

get3P :: Parser Int
get3P = PsrOf get3
这里的记录语法只是用来简化类型的定义,而不是编写

dePsr get3P "38" -- Just ("8", 3)
dePsr get3P ""   -- Nothing
dePsr get3P "hello" -- Nothing

记录语法的其他用法(模式匹配或稍微修改值的副本)实际上并不适用于包装单个值的类型。

您已经创建了类型。现在您想要创建该类型的值。为此,您需要使用类型
字符串->的值调用
PsrOf
(字符串,a)
。例如:

<interactive>:5:7: error: parse error on input ‘"’
要实际使用解析器,需要先提取函数,然后再将其应用于字符串:

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

get3 :: String -> Maybe (String, Int)
get3 ('3':xs) = Just (xs, 3)
get3 _ = Nothing  -- Any string, including the empty string, that doesn't start with '3'

get3P :: Parser Int
get3P = PsrOf get3
这里的记录语法只是用来简化类型的定义,而不是编写

dePsr get3P "38" -- Just ("8", 3)
dePsr get3P ""   -- Nothing
dePsr get3P "hello" -- Nothing

记录语法的其他用法(模式匹配或对值进行稍微修改的副本)实际上并不适用于包装单个值的类型。

PsrOf
需要一个函数,而不是字符串。您正在将解析器构造与解析器应用程序混为一谈。假设
f::string->Maybe(string,a)
,您可能需要类似于
dePsr(PsrOf)“hello”
。您使用的记录语法仅适用于修改现有解析器。类似于
让oldParser=PsrOf someFunc在oldParser{dPsr=newFunc}
中。(对于封装单个值的类型来说,这没有什么意义。它更适合于在更改一个更复杂对象的同时复制它。)
PsrOf
需要一个函数,而不是字符串。您正在将解析器构造与解析器应用程序混为一谈。假设
f::string->Maybe(string,a)
,您可能需要类似于
dePsr(PsrOf)“hello”
。您使用的记录语法仅适用于修改现有解析器。类似于
让oldParser=PsrOf someFunc在oldParser{dPsr=newFunc}
中。(对于封装单个值的类型来说,这并没有什么意义。它更适合于在更改一个更复杂对象的同时复制该对象。)您的下一项工作是为这种类型生成一个Monad实例。您可能会发现它很有用:@PaulJohnson是吗?Monad实例很有用,但不是真正必要的。@Cubic您还打算如何编写一系列子子句,如“赋值::=identifier'=”表达式“?是的,您可以从头开始创建自己的排序运算符,但这将是一件非常愚蠢的事情。您的下一项工作是为这种类型创建一个Monad实例。您可能会发现这很有用:@PaulJohnson是吗?Monad实例很有用,但不是真正必要的。@Cubic否则您将如何编写一系列子子句,例如?”“赋值::=identifier'='expression”?是的,您可以从头开始创建自己的排序运算符,但这将是一件非常愚蠢的事情。