2012-02-13 13 views
1

私はこれを複数の方法で試しました。if-then-else、ガード、case文ですが、コンパイルできません。私はコードから、私がしたいことがはっきりしていると思います。なぜこれはできないのですか?そしてそれを真っ直ぐにするために私は何をしなければなりませんか?ここでif-then-elseに何が間違っていますか?

appendMsg :: String -> (String, Integer) -> Map.Map (String, Integer) [String] -> Map.Map (String, Integer) [String] 
appendMsg a (b,c) m = do 
     let Just le1 = length . concat <$> Map.lookup (b,c) m 
      le2 = le1 + length a 
     if le2 < 1400 then (let m2 = Map.adjust (x ++ [a]) (b, c) m) else (print (le1, le2)) 
     return (m2) 

エラーメッセージはparse error on input `)'です。角括弧を変更するとparse error on input `else'が得られます。 elseパス(m2 = mとする)で言うと、ブラケットエラーが再び発生します。私が達成しようと何

は、他の機能はappendMsgとappendMsgと同じ引数を取り、そのLE2> 1400と呼ばれるべき場合LE2 < = 1400その後、m2は

f x = x ++ [a] 
m2 = Map.adjust f (b, c) m 

を使用して作成する必要がある場合、あります単に何も返さないはずです。

追加の問題は、これは右下のすべての勧告に従って設定されるとすぐということである。

if le2 < 1400 then let m2 = Map.adjust (++ [a]) (b, c) m in return (m2) else return()

私は道で同じである

No instance for (Monad (Map.Map (String, Integer))) 
     arising from a use of `return' 

を言ってエラーが出ますエラー私は最終的に私がガードを使用した。問題は、この奇妙なタイプの残りのコードでは私ができることがほとんどないということです。どのようにしてこの型を(Map.Map(String、Integer)[String])に変換したり、それを完全に避けることができますか?

+0

一般的には、どのようなエラーメッセージが表示されるかを含めることをお勧めします。 – Amber

+3

'le2> = 1400'の場合と同じ' m2'とは何ですか? – rampion

+3

'else'パスをたどった場合はどうなりますか? –

答えて

2

あなたはその結果Monadインスタンスでなければならないdoを、使用しているが、あなたの関数の型は、それがMonadのインスタンスではありませんMapを返すことを示しています。あなたが本当にNothingときle2 >= 1400を返すようにしたい場合は、ときle2 < 1400Just ...を返却する必要があります、そしてあなたの関数は次のようになります。それが鍵を見つけることができない場合、この関数はNothingを返します

import qualified Data.Map as Map 
import Control.Monad 

appendMsg :: String -> (String, Integer) -> 
      Map.Map (String, Integer) [String] -> 
      Maybe (Map.Map (String, Integer) [String]) 
appendMsg a k m = do 
     v <- Map.lookup k m 
     let l = length . concat $ v 
      l' = l + length a 
     guard $ l' < 1400 
     return $ Map.insert k (v ++ a) m 

に留意されたいです。 Mapで始まる...

+0

$は省略記号()ですか? –

+0

'$'は関数アプリケーションの優先順位の低い形式です。 'f a $ g b'は' f a(g b) 'に相当します。これは主に括弧を削除するためのものですが、 'fs 'の各関数を引数' a'に適用する 'map($ a)fs'のように関数アプリケーションを関数として扱いたい場合や、リスト)。 – pat

+0

Monadインスタンスの問題は本当に 'do'ですか?これは 'guard'とMonadPlusの使用に関連していないのでしょうか? –

4

letのいずれかに、inが続かなければなりません。または、ブロックdoのすぐ内側にある必要があります。 letは、doブロックの最後の文であってはなりません。これらのルールは、使用の可能性なしにすぐに有効範囲外に出る変数を作成することは意味を成さないという事実の結果です。

ifthenブランチの内部にm2という変数を作成しますが、使用することはありません。あなたはifの外でそれを使用しようとしますが、ifm2の外には存在しません。 ifの外側に作成された変数は使用できません。 ifの条件がfalseの場合、m2の値はどうなりますか?

+0

le2 <= 1400の場合、ローカル変数m2を作成します。 –

+2

@JFritsch:あなたのコードは常に 'm2'を返しています。 'le2> 1400'なら何が起こると思いますか? –

+0

@KevinBallardこの場合、私のキューをフラッシュする他の関数を呼びたいと思う。印刷物はダミーコードのみです。 –

関連する問題