2017-11-25 6 views
0

ハスケルに多くの問題を抱えているクラスの小さな課題に取り組んでいます。私は整数がリストの一部であるかどうかを見つけるための再帰的なメソッドを作成しようとしています。私はその要点を知っていますが、haskell構文で正しく機能するようにはできません。現在のリストが空であるかどうかをチェックし、そうであればFalseを返し、整数が現在のリストの先頭と等しいかどうかをチェックし、Trueであれば検索している値と同じ値で再度メンバーを呼び出し、リスト。これを正しく機能させるためには何ができますか?ハスケルのメンバー関数

member ::Int -> [Int] -> Bool 
member x y 
if y [] then False 
else if x == head y then True 
else member x tail y 

私も初めラインとして

member :: (Eq x) => x -> [x] -> Bool 

を使用してみましたが、また多くのsimplier:

let member x y = if null y then False 
else if x == head y then True 
else member x tail y 

すべてのヘルプ

は現在、これは私が持っているものです感謝されます。あなたがより明確にそれを書くことができますパターンマッチングと

+0

$を追加すると、元のバージョンが機能します。アプリケーションは左結合です。 – bipll

+0

これを追加しましたが、今このエラーが発生しています。解析エラー:トップレベルでの裸の表現 おそらく、あなたはTemplateHaskellを使用しようとしていたでしょう – Elmangos

+0

適切な字下げを忘れていませんか? – bipll

答えて

3

member :: (Eq a) => a -> [a] -> Bool 
member x [] = False 
member x (y:ys) | x==y = True 
       | otherwise = member x ys 
+0

私はこれを使用すると、私はエラーを取得:実際の型を持つ•予想と一致しませんでし型 'IOのT2' 'ブール' •Inを式:main IOアクション 'main'のタイプをチェックするとき – Elmangos

+0

これは、あなたが 'main'を間違って書いたからです。この 'element'の実装は問題ありません。 – HTNW

+0

主な機能はどのように見えるのですか?私は現在、main = doメンバー1を持っています。[1 2 3] – Elmangos

3
element _ [] = False 
element e (x:xs) = e == x || e `element` xs 
-- OR 
element e xs = if xs == [] then False 
       else if e == head xs then True 
        else e `element` tail xs 
-- OR 
element e xs = xs /= [] && (e == head xs || e `element` tail xs) 
-- x `op` y = op x y 

-- If you're feeling cheeky 
element = elem 
あなたの構文は非常に混乱して表示されますが、あなたのロジックは覚えているもののバケットリストをので、ここで、理にかなってい

  • 関数は複数の方程式で定義できます。方程式は上から下にチェックされます。それは=を使用していることを意味します。

  • パターン一致は、の同等性テストではありません。パターンマッチは、一致した場合は値をその構成要素に分割し、そうでない場合は失敗します。同等性テストx == yは、xyの等価についてBoolを返します。

  • パターンマッチングは

    element _ []  = ... 
    element e (x:xs) = ... 
    

    ノートのように、

    case xs of { 
        [] -> ... 
        x:xs' -> ... 
    } 
    
  • 複数の式のように、...を介したフロー制御のため

    • case文が使用されていることを_のパターン内の値を無視できます。複数の引数を持つ関数の複数の方程式を使用すると、実際には一度にすべての引数に対してパターンマッチングを行うことになります。

  • Bool Sはif _ then _ else _を介して、フロー制御のために使用される:

    本当に

    case x == y of { 
        True -> False 
        False -> True 
    } 
    

    Bool sは通常のオペレータ(&&)infixr 3)を使用し、(||)できている

    if xs == [] then False 
          else True 
    

    infixr 2

  • 違いは特にリストには珍しいです。 instance Eq a => Eq [a]ですので、==をリストに使用するには、リストの要素を比較して同等かどうかを知る必要があります。これはちょうど(== [])をチェックしているときにも当てはまります。 [] == []は実際にはエラーを引き起こします。なぜなら、コンパイラはその要素がどのような型かを知ることができないからです。これは問題ではありませんが、あなたが言うならば、たとえばnonEmpty xs = xs /= []の場合、nonEmpty :: [a] -> Boolの代わりにnonEmpty :: Eq a => [a] -> Boolが得られるので、の場合はnonEmpty [not]がタイプエラーとなります。

  • 機能アプリケーションは、最高の優先順位を持ち、左結合される:((element x) xs)

  • element x tail xsがここ
  • 意味をなさない(((element x) tail) xs)、として読み込むよう

    • element x xs読み取りf $ x = f xですが、それはinfixr 0です。これは、基本的にルールを逆転させ、親の大きなセットのように機能することを意味します

      • x `element` tail xs((element x) (tail xs))、あまりにも
    • を意味します。その右引数の周りの

      • element x $ tail xs
    • 中置関数は常に接頭アプリケーションよりも低い優先順位を持って働く、((element x) (tail xs))として読み込みます

    • let decls in exprの式です。 declsexprのスコープ内にあり、その全体がexprと評価されます。トップレベルでは意味がありません。

    • ハスケルは、Pythonのように構造コードにインデントを使用します。 Reference