2017-12-05 19 views
0

を一致させる方法がわからない、私は解決するために、このHaskellの質問があります:ハスケル:私はそう種類

入力に機能fと入出力アクションaと結果を受け取るmapIO関数を定義し、実行されると、与えられたアクションaを実行し、aの戻り値にfというアプリケーションを返します。ここで

は私のコードです:

mapIO f a = do b <- a 
       return f(b); 

それはコンパイルが、それは動作しません。次の実行例と同じことをしようとすると、動作しません。どうか、誰かが私を助けることができますか?他の多くの言語で

Prelude Data.Char> mapIO even readLn 
75 
False 
+3

どうしたらうまくいかないのですか? '75'は奇妙なので、' IO'で囲まれた 'False'である' IO Bool'を取得します。 –

+2

'return f(b);'は 'return $ f b'または' return(f b) 'でなければなりません。 @WillemVanOnsem私はそれが実際の出力ではなく、実際の出力ではないと考えています。 – Zpalmtree

+0

'return f(b)'は 'return fb'として解析されます。つまり' f'と 'b' 。 'return'はあなたが期待するキーワードではありません(つまり、多くの命令/ OO言語のように)、関数の適用優先​​順位の通常の規則に従います。 – user2407038

答えて

8

g(x)は引数xに機能gを適用するための構文です。ハスケルでは、並行して十分なので、g xgxに適用します。偶然の一致では、これはg(x)が、g(x)は、関数適用のための正しい構文であると思われるかもしれない初心者のため、xと同じ値(x)gを適用有効な構文であることを意味します。しかし、そうではありません、そしてその混乱があなたにここで噛まれました。

return f(b)と書く場合、これは特殊な構文returnを使用することを意味し、返されるものは関数アプリケーションf(b)である必要があります。しかし、returnは、それ自体Haskellの関数です。したがって、実際には、returnを関数fに適用し、その結果を(b)という用語に適用することです。 (その意味で、関数アプリケーションは「左結合」です。)

幸いにも、関数アプリケーションの結合性の問題は、他の結合性の問題と同様にかっこを使用することです。だから、:

return (f(b)) 

または、偶然正しい余分な括弧なし:

return (f b) 

これはreturn f(b)形で(コンパイルされ、型にチェックの意味での)「働いていた」理由の唯一の問題を残し。これは高度な話題です。関数はreturn = constMonadを形成していることがわかります。return f(b)は実際にはconst f(b)を意味し、(b)という用語を投げ捨てました。 (別に:Monadの関数インスタンスの使用が許可されることに加えて、我々もここMonadの関数インスタンスを使用する必要があり、我々は(b)return fを適用しているので、return fの種類は関数でなければなりません。)ある

mapIO' f a = do b <- a 
       f 

:だからあなたの定義が同じだった、それは別の入力/出力アクションであるかのようにまず、aを行い、その結果を捨て、その後、fを行います。

mapIO :: Monad m => m b -> m t -> m b 

おっと:あなたはmapIOのための推論種類を確認した場合、あなたはそれが、この直感に合致した表示されます!