2016-10-16 19 views
1

私はHaskell(および関数型プログラミング)の完全な初心者です。だから、頭と++で型を一致させることができません

--Datatype for a cipher 
type Cipher = String 

validateCipher :: Cipher -> Bool 
validateCipher ciph = 
    if((length ciph) /= 26)then 
     False 
    else if(let savedChars = "" in vCiph ciph savedChars)then 
     True 
    else 
     False 

vCiph :: Cipher -> String -> Bool 
vCiph c sChars = 
    if(elem (head c) sChars)then 
     False 
    else if(length c == 0)then 
     True 
    else 
     sChars ++ (head c) 
     vCiph (tail c) sChars 

Ciphers.hs:24:25: 
    Couldn't match expected type ‘Bool’ with actual type ‘[Char]’ 
    In the expression: sChars ++ (head c) 

Ciphers.hs:24:41: 
    Couldn't match type ‘Char’ with ‘[Char]’ 
    Expected type: [[Char]] 
     Actual type: Cipher 

これは私が実行しようとしているコードは次のとおりです。コードのかなりシンプルな作品をしようとしたとき、私はこの問題に遭遇しましたそれは本当に問題を引き起こしている最後の2つの行であり、私は理由を理解できません。正直なところ、最初の1つでは期待される型がboolである理由、なぜコンパイラの列番号がNotepad ++のものと一致しないのか、またはelse文の後に2行のコードを持つことが許されているかどうかはわかりません。どんな助けでも大変感謝しています。

+1

「sChars ++(head c)vCiph(tail c)sChars」が何を意味するものであるかを理解しようとしています。 1つの式ですが、改行は何も意味しません。 –

+0

ああ、本当ですか?私が真のハスケル・ノブだと言うとき、私は本当にそれを意味しています。私はライン・ブレイクがaの代わりに2つのステートメントを分けることを期待していました。 (他のすべての言語のように)。これらの行は、保存された文字のリストに最初の文字を追加して再帰することを目的としています。暗号はアルファベットの各文字の1つだけを含むことを確認することがポイントです。 –

+1

ああ、あなたは、改行がハスケルの文を別々にするのは間違いありません。必要に応じて明示的に ';'を使用することもできます。しかし、あなたは何の記述も書いていません - あなたは純粋な機能を書いています。 –

答えて

3

まず、「非常に簡単な」方法があります。

import Data.List 

type Cipher = String 

validateCipher :: Cipher -> Bool 
validateCipher c = sort c == ['a'..'z'] 

次に、あなたが何をしようとしていた何のための修正があります:

type Cipher = String 

validateCipher :: Cipher -> Bool 
validateCipher ciph = length ciph == 26 && vCiph ciph "" 

vCiph :: Cipher -> String -> Bool 
vCiph "" _ = True 
vCiph (c:cs) prev 
    | elem c prev = False 
    | otherwise = vCiph cs (c:prev) 

私はあなたのコードに気づいたいくつかのこと:

  • コードチェックはhead csCharsである場合その後、cが空であるかどうかをチェックします。しかし、cが空の場合は、head cが例外をスローするため、遅すぎます。

  • コードsChars ++ (head c)は、sCharsを変更しません。新しいリストが作成されます。 head cCharあり、++両側が[Char]する必要があるため

  • コードsChars ++ (head c)型エラーです。

新バージョンでは、パターンマッチングで物事を達成:あなたのための頭と尾に引数を分割(c:cs)パターンを、あなたが明示的にheadtailを呼び出す必要はありません。 ""のパターンは空の文字列と一致するため、length c == 0をテストする必要はありません。 Cipherは限り型システムがあるとして、もはやStringになるように、代わりにtypenewtypeがそれをしない使用

newtype Cipher = Cipher String 

validateCipher :: Cipher -> Bool 
validateCipher (Cipher ciph) = length ciph == 26 && vCiph ciph "" 
    where 
    vCiph :: String -> String -> Bool 
    vCiph "" _ = True 
    vCiph (c:cs) prev 
     | elem c prev = False 
     | otherwise = vCiph cs (c:prev) 

:ここ

CipherStringも持っていることについて、あなたの懸念に対処、スタイルのフィックスアップです心配している。その中に文字列の入ったボックスと考えてください。 ほとんどエッジケースを除いて data Cipher = Cipher Stringと同じものです。

vCiphvalidateCipherとすると、vCiphは他の機能から呼び出されることはないことが明らかです。

+0

うわー、私は+1以上の答えを与えることができれば、私はそうです。私はそれが私が数週間で学んだより1ページで多くを教えてくれたと思う。そんなにありがとう! –

関連する問題