Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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_Functor - Fatal编程技术网

Haskell 分析器的函子

Haskell 分析器的函子,haskell,functor,Haskell,Functor,作为家庭作业的一部分,我们正在Haskell中研究解析器。我们有这种数据类型 newtype Parser a = Parser { parse :: String -> Maybe (a,String) } 这对我来说很清楚,我们的解析器得到的字符串是类型a的返回表达式和剩余的未解析字符串 但接下来我们要做的是函子定义: instance Functor Parser where fmap f p = Parser $ \s -> (\(a,c) ->

作为家庭作业的一部分,我们正在Haskell中研究解析器。我们有这种数据类型

newtype Parser a = Parser { parse :: String -> Maybe (a,String) } 
这对我来说很清楚,我们的解析器得到的字符串是类型a的返回表达式和剩余的未解析字符串

但接下来我们要做的是函子定义:

  instance Functor Parser where
       fmap f p = Parser $ \s -> (\(a,c) -> (f a, c)) <$> parse p s
实例函子解析器,其中
fmap fp=Parser$\s->(\(a,c)->(fa,c))parse ps
我完全迷路了。在我看来,parse p s给出了从类型a解析的表达式,但我无法理解这个fmap实际上在做什么,以及为什么它有意义

希望有人能给我一个线索


谢谢

给定一个解析器
p
fmap fn p
将创建一个新的解析器,解析与
p
相同的文本,然后将
fn
应用于输出。例如,如果您有一个解析器
parseOptionalNumber::parser(可能是Int)
,您可以通过从just parseOptionalNumber执行
parseNumber=fmap将其转换为
parseNumber::parser Int
(尽管您不想这样做,因为just
是部分的)

至于实现,它的工作原理如下:

  • 整个过程被包装在
    Parser$\s->…
    中,它创建了一个新的解析器,在给定输入字符串
    s
    的情况下执行
  • parse p s
    使用函数
    parse::Parser a->(String->Maybe(a,String))
    (根据
    Parser a
    的定义)在输入字符串
    s
    上运行输入解析器
    p
    ,生成类型为
    Maybe(a,String)
    的输出
  • ()
    是函数
    fmap
    的同义词,但作为运算符而不是函数。它将左侧的函数映射到右侧的
    Maybe(a,String)
    输出。它映射的函数是
    \(a,c)->(fa,c)
    ,它在给定解析器
    p
    的输出
    (a,c)
    上运行给定函数
    f
希望这是有意义的;如果没有,您可能会发现以不太紧凑的形式重写
fmap
更有用:

实例函子解析器,其中
fmap f inParser=Parser$\inputStr->
的案例(parse inParser inputStr)
无->无
Just(result,leftoverString)->Just(f result,leftoverString)

给定一个解析器
p
fmap fn p
将创建一个新的解析器,该解析器解析与
p
相同的文本,但随后将
fn
应用于输出。例如,如果您有一个解析器
parseOptionalNumber::parser(可能是Int)
,您可以通过从just parseOptionalNumber
执行
parseNumber=fmap将其转换为
parseNumber::parser Int
(尽管您不想这样做,因为just
是部分的)

至于实现,它的工作原理如下:

  • 整个过程被包装在
    Parser$\s->…
    中,它创建了一个新的解析器,在给定输入字符串
    s
    的情况下执行
  • parse p s
    使用函数
    parse::Parser a->(String->Maybe(a,String))
    (根据
    Parser a
    的定义)在输入字符串
    s
    上运行输入解析器
    p
    ,生成类型为
    Maybe(a,String)
    的输出
  • ()
    是函数
    fmap
    的同义词,但作为运算符而不是函数。它将左侧的函数映射到右侧的
    Maybe(a,String)
    输出。它映射的函数是
    \(a,c)->(fa,c)
    ,它在给定解析器
    p
    的输出
    (a,c)
    上运行给定函数
    f
希望这是有意义的;如果没有,您可能会发现以不太紧凑的形式重写
fmap
更有用:

实例函子解析器,其中
fmap f inParser=Parser$\inputStr->
的案例(parse inParser inputStr)
无->无
Just(result,leftoverString)->Just(f result,leftoverString)

有一件事让定义变得更加混乱,那就是元组将结果存储在第一个位置。如果是第二个,那么您可以使用元组本身的函子实例来获取
fmap f p=Parser$\s->fmap f parse p s
(也就是说,
挖掘
Maybe
值,然后
fmap
挖掘元组。)有一件事使得定义比它需要的更令人困惑,那就是元组将结果存储在第一个位置。如果是第二个,那么您可以使用元组本身的函子实例,以获得
fmap f p=Parser$\s->fmap f parse p s
(即,
挖掘
Maybe
值,并且
fmap
挖掘元组。)(旁注)即
fmap fp=Parser(\s->do{(r,q)[(fr,q)|(r,q)(旁注),即…
fmap fp=Parser(\s->do{(r,q)[(fr,q)|(r,q)