1

Prog Aが正常にコンパイルおよび実行されるのに、Prog Bがコンパイルに失敗するのはなぜですか?ありがとう

Prog A

func :: String -> String
func a = a

mydofn a = do 
  x <- func a
  return x

main = print "Finished"

プログラムB

func :: Int -> Int
func a = a

mydofn a = do 
  x <- func a
  return x

main = print "Finished"

Prog Bコンパイルエラー:

Couldn't match expected type `m0 t0' with actual type `Int'
In the return type of a call of `func'
In a stmt of a 'do' block: x <- func a
In the expression:
  do { x <- func a;
       return x }
4

2 に答える 2

6

do 表記を使用すると、このコードは次のようになります。

mydofn a = do 
  x <- func a
  return x

は単なるシンタックスシュガーです

mydofn a = func a >>= (\x -> return x)

今、>>=type を持っていますがMonad m => m a -> (a -> m b) -> m b、2 番目の例では、アプリケーションfunc aには typeIntがあり、統合できませんMonad m => m a(Int一部の内部ではなく、独自のmものであるため)。」)。しかし、なぜこれが最初のケースで機能したのでしょうか?m aInt

Haskell の文字列は単なる文字のリストです ( [Char])。そして、標準ライブラリには次のようなインスタンスMonadがあります。[a]

instance  Monad []  where
    m >>= k             = foldr ((++) . k) [] m
    return x            = [x]

したがって、 (with and ) と[Char]統合され、最初の例は次のようになりますMonad m => m am = []a = Char

mydofn a = foldr ((++) . (\x -> [x])) [] (func a)

または同等に

mydofn a = concat . map (\x -> [x]) $ func a

これは、文字列の各文字をシングルトン文字列にマップし ("abc"にマップされます["a", "b", "c"])、結果のすべての文字列を連結します (["a", "b", "c"]になります"abc")。

于 2012-11-11T14:20:38.943 に答える
4

prog A では、 list モナドを使用していますString = [Char]。Int モナドはありません!プログAでは、

mydofn a = do 
  x <- func a
  return x

と同等です

mydofn a = [x | x <- func a]

したがって、実際にはリストの要素を実行するだけで、何も変更しません。

prog A, m0 t0matchesではas と[] Char書くことができないため、prog B でエラーが発生しました。Intm0 t0


はとmydofn同等です

mydofn a = do 
  func a

これは と同等mydofn a = func aで、 と同じ意味mydofn a = aです。

これは、質問を明確にするための省略された例だと思います。他に何をしたかったmydofnですか?

多分あなたは意味した

mydofn a = do 
  x <- return (func a)
  return x

これにより、Intで機能しますが、あなたの目的が何であるかはまだわかりません。

于 2012-11-11T14:15:44.560 に答える