簡體   English   中英

將折痕轉換為單折痕haskell

[英]Converting a fold to a monadic fold haskell

我在將自定義數據類型的折疊轉換為單折時遇到一些困難。 這個想法是我應該能夠折疊IO或者Maybe使用>>= 但是,我遇到了我不完全理解的錯誤。

這是我的代碼:

data RTree a = Val a | Question String [RTree a] deriving (Show)

foldRT :: (a -> b) -> (String -> [b] -> b) -> RTree a -> b
foldRT v q (Val x) = v x 
foldRT v q (Question s xs) = q s $ map (foldRT v q) xs



foldRTM :: (Monad m) => (a -> m b) -> (String -> [b] -> m b) -> RTree a -> m b 
foldRTM v q t = foldRT (>>= v) q' (mon t)
   where q' s ls = mapM id ls >>= (\xs -> q s xs) 
         mon (Val x) = Val $ return x
         mon (Question s xs) = Question s (map return xs)

這是錯誤消息:

main.hs:14:36: error:
    • Couldn't match type ‘m’ with ‘RTree’
      ‘m’ is a rigid type variable bound by
        the type signature for:
          foldRTM :: forall (m :: * -> *) a b.
                     Monad m =>
                     (a -> m b) -> (String -> [b] -> m b) -> RTree a -> m b
        at main.hs:13:1-78
      Expected type: RTree (m a)
        Actual type: RTree (RTree a)
    • In the third argument of ‘foldRT’, namely ‘(mon t)’
      In the expression: foldRT (>>= v) q' (mon t)
      In an equation for ‘foldRTM’:
          foldRTM v q t
            = foldRT (>>= v) q' (mon t)
            where
                q' s ls = mapM id ls >>= (\ xs -> q s xs)
                mon (Val x) = Val $ return x
                mon (Question s xs) = Question s (map return xs)
    • Relevant bindings include
        q' :: String -> [m b] -> m b (bound at main.hs:15:10)
        q :: String -> [b] -> m b (bound at main.hs:14:11)
        v :: a -> m b (bound at main.hs:14:9)
        foldRTM :: (a -> m b) -> (String -> [b] -> m b) -> RTree a -> m b
          (bound at main.hs:14:1)
   |
14 | foldRTM v q t = foldRT (>>= v) q' (mon t)
   |                                    ^^^^^

這個想法是>>= vq'作為foldRT參數使其類型...

(Monad m) :: (m a -> m b) -> (String -> [m b] -> m b) -> RTree m a -> m b

...但是將樹的初始輸入轉換成這種形式的映射似乎不起作用。 我認為這是我的愚蠢誤解。

謝謝!

問題出在這里:

     mon (Question s xs) = Question s (map return xs)

其中return具有RTree a -> RTree (RTree a)

您可能打算:

     mon (Question s xs) = Question s (map (fmap return) xs)

同樣, foldRTM可以簡化為:

foldRTM :: (Monad m) => (a -> m b) -> (String -> [b] -> m b) -> RTree a -> m b 
foldRTM v q t = foldRT (>>= v) q' (return <$> t)
   where q' s ls = sequence ls >>= q s

如果您創建Functor RTree適當實例:

instance Functor RTree where
    fmap f (Val x) = Val (f x)
    fmap f (Question s xs) = Question s (map (fmap f) xs)

暫無
暫無

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

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