簡體   English   中英

使用 <|> 運算符理解函數

[英]Understanding function with <|> operator

我有以下類型:

newtype Rep f a = Rep { runRep :: String -> f (String, a) }

Rep fa類型是一種有狀態計算,它以String作為初始狀態,並生成(String, a)作為計算結果。 計算結果包含在函子f

Rep的 Applicative 實例如下:

instance Monad f => Applicative (Rep f) where 
    pure x = Rep $ \s -> pure (s, x)
    Rep f <*> Rep x = Rep $ \s -> do 
        (s',rf)  <- f s 
        (s'',rx) <- x s'
        return (s'', rf rx)

Rep的 Monad 實例如下:

instance Monad f => Monad (Rep f) where 
   return x = pure x 
   Rep a >>= f = Rep $ \s -> do
      (s', ya) <- a s
      let (Rep f') = f ya
      (s'', yf) <- f' s'
      pure (s'', yf)

Rep的替代實例如下:

instance (Monad f, Alternative f) => Alternative (Rep f) where 
    empty = Rep (const empty)
    Rep a <|> Rep b = Rep $ \s -> a s <|> b s

我有以下數據類型和功能:

data TD = Empty | Fol TD TD | Letters [Char] | Str TD
data Res = Nil | Character Char | Cop Res Res | Special [Res]

findmatch :: (Monad f, Alternative f) => TD -> Rep f Res

findmatch (Str a) =
   frontAdd <$> findmatch a <*> findmatch (Str a)
   <|> pure (Special [])
      where
      frontAdd x (Special xs) = Special (x:xs)
      frontAdd _ _ = error "Not possible."

我無法理解上述功能。 函數frontAdd創建一個包含[Res]列表的Special值。 findmatch返回Rep f Res frontAdd <$> findmatch a <*> findmatch (Str a)frontAdd應用於findmatch afindmatch (Str a)返回的Res

但是,我不確定使用模式匹配的這一行如何工作: frontAdd x (Special xs) = Special (x:xs) 此外,假設仿函數f[ ]會怎么<|>frontAdd <$> findmatch a <*> findmatch (Str a) <|> pure (Special [])工作? 我知道如果函子fMaybe ,那么<|>會做出左偏的選擇,但我不知道<|>是如何專門用於列表的。 在文檔中它指出:

instance Alternative [] where
  empty = []
  (<|>) = (++) -- length xs + length ys = length (xs ++ ys)

串聯究竟是如何工作的? 我說frontAdd <$> findmatch a <*> findmatch (Str a)的結果與空列表連接是否正確?

任何見解表示贊賞。

首先,如果f[] ,那么pure (Special [])[(Special [])] ,也就是[Special []]

其次,列表拼接是最自然的事情,用

  [a, b, c, d, ...]  ++  [p, q, r, s, ...]
==
  [a, b, c, d, ...   ,    p, q, r, s, ...]

IE

(x:xs) ++ ys  =  x : (xs ++ ys)
[]     ++ ys  =             ys

也就是說,

   xs  ++ ys  =  foldr (:) ys xs

因此

  [a, b, c]  <|>  [Special []]
==
  [a, b, c,        Special []]

  []         <|>  [Special []]
==
  [                Special []]

所以不, <|> pure (Special [])不與空列表連接,而是與一個包含空列表的Special列表連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM