1

ツリーを表す新しいデータ型を定義しました。ツリーのすべての要素をウォークオーバーする関数も実装しました。関数walkの機能バージョンは正しいですが、彼のモナディックバージョンは正しくありませんwalkM

module Hdot where
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map

data RDoll a = Null | RDoll a [RDoll a] deriving (Show)    

test :: RDoll Int
test = RDoll 1 [RDoll 2 [Null], RDoll 3 [RDoll 4 [Null]]]

walk :: (a -> b) -> RDoll a -> [b]

walk f Null          = []
walk f (RDoll x rds) = ((f x): (concatMap (\x -> walk f x) rds))

walkM :: (Monad m) => (a -> m b) -> RDoll a -> m [b]
walkM f Null            = return []
walkM f (RDoll rd rdss) = do
  x <- f rd
  xs <- concatMap (walkM f) rdss
  return (x:xs) 

タイプエラーがあります

Couldn't match type `b' with `[b]'
...

誰かが私を助けることができますか?

返信ありがとうございます。

4

1 に答える 1

7

貴重なコンテキストがあるため、通常、完全なエラーメッセージを表示する必要があります。

A.hs:19:26:
    Could not deduce (m ~ [])
    from the context (Monad m)
      bound by the type signature for
                 walkM :: Monad m => (a -> m b) -> RDoll a -> m [b]
      at A.hs:(16,1)-(20,15)
      `m' is a rigid type variable bound by
          the type signature for
            walkM :: Monad m => (a -> m b) -> RDoll a -> m [b]
          at A.hs:16:1
    Expected type: [b]
      Actual type: m b
    Expected type: a -> [b]
      Actual type: a -> m b
    In the first argument of `walkM', namely `f'
    In the first argument of `concatMap', namely `(walkM f)'

[b]したがって、値のリストとアクションの間にはいくつかの混乱がありますm b

walkM疑わしいコードは、再帰的に実行するためのconcatMapの使用です。私はあなたが使うつもりだと思いますconcatMapM(例えばmapMそしてconcat):

walkM :: (Monad m) => (a -> m b) -> RDoll a -> m [b]
walkM f Null            = return []
walkM f (RDoll rd rdss) = do
  x  <- f rd
  xs <- mapM (walkM f) rdss
  return (x:concat xs)

スタイルについてのメモとして、私は少し違った書き方をしようと思います。ベースライブラリのバラの木を見てください。特に、 Functor、Monadのインスタンスを定義walkおよび定義したり、既存のライブラリ関数を再利用したりしないでください。walkM

于 2012-04-26T11:53:38.643 に答える