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”?是的,您可以从头开始创建自己的排序运算符,但这将是一件非常愚蠢的事情。