简体   繁体   English

Haskell-尝试Monad实例-语法问题

[英]Haskell - Attempting Monad instance - syntax issues

I have the following definitions: 我有以下定义:

newtype Parser a = Parser { parse :: String -> [(a,String)] }


instance Functor Parser where
 fmap g (Parser pa) = Parser { parse = \s -> [(g a,s') | (a,s') <- pa s] }


instance Applicative Parser where
 pure x = Parser { parse = \s -> [(x,s)] }
 (<*>) (Parser pg) (Parser pa) = Parser { parse = \s -> [(g a,s'') | (g,s') <- pg s, (a, s'') <- pa s'] }



instance Monad Parser where
 return = pure
 (>>=) (Parser pa) g = Parser { parse = \s -> [(b,s'') | [(a, s')] <- (pa s), [(b,s'')] <- (g a) s'] } 

The trouble is with the bind operator implementation. 问题在于绑定运算符的实现。 I am not sure why I get type error there. 我不确定为什么会在那里输入类型错误。 I am attempting to define the bind operator on the same lines as (<*>) 我正在尝试在与(<*>)相同的行上定义绑定操作符

The error is: 错误是:

parser.hs:17:58: error:
    • Couldn't match expected type ‘(a, String)’
                  with actual type ‘[(a, t0)]’
    • In the pattern: [(a, s')]
      In a stmt of a list comprehension: [(a, s')] <- (pa s)
      In the expression:
        [(b, s'') | [(a, s')] <- (pa s), [(b, s'')] <- (g a) s']
    • Relevant bindings include
        g :: a -> Parser b (bound at parser.hs:17:20)
        pa :: String -> [(a, String)] (bound at parser.hs:17:16)
        (>>=) :: Parser a -> (a -> Parser b) -> Parser b
          (bound at parser.hs:17:2)
   |
17 |  (>>=) (Parser pa) g = Parser { parse = \s -> [(b,s'') | [(a, s')] <- (pa s), [(b,s'')] <- (g a) s'] }
   |                                                          ^^^^^^^^^

parser.hs:17:92: error:
    • Couldn't match expected type ‘t0 -> [[(b, String)]]’
                  with actual type ‘Parser b’
    • The function ‘g’ is applied to two arguments,
      but its type ‘a -> Parser b’ has only one
      In the expression: (g a) s'
      In a stmt of a list comprehension: [(b, s'')] <- (g a) s'
    • Relevant bindings include
        s' :: t0 (bound at parser.hs:17:63)
        g :: a -> Parser b (bound at parser.hs:17:20)
        (>>=) :: Parser a -> (a -> Parser b) -> Parser b
          (bound at parser.hs:17:2)
   |
17 |  (>>=) (Parser pa) g = Parser { parse = \s -> [(b,s'') | [(a, s')] <- (pa s), [(b,s'')] <- (g a) s'] }

Update: For the sake of completeness, based on the answers. 更新:为了完整起见,基于答案。 Here is what worked: 这是起作用的:

instance Monad Parser where
 return = pure
 (>>=) (Parser pa) g = Parser { parse = \s -> [(b,s'') | (a, s') <- (pa s), (b,s'') <- parse (g a) s'] } 

A guard pattern like [(a, s')] <- (pa s) means you're expecting pa s to return a list of lists with each exactly one pair of a and s in them, whereas it actually returns just a list with any number of those pairs in them. [(a, s')] <- (pa s)类的保护模式意味着您期望pa s返回一个列表列表,每个列表中正好有一对as ,而实际上它仅返回一个列表与其中任何数量的对。

Basically, drop the brackets (and also from the other binding) and then it should work. 基本上,放下括号(以及从其他绑定中放下),然后它应该起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM