2012-01-01 12 views
7

私はHaskellを初めて使いました。私はいくつかのチュートリアルを試しています。 私はこのスクリプトを書いた:Haskellで関数を定義する正しい方法

lucky::(Integral a)=> a-> String 
lucky 7 = "LUCKY NUMBER 7" 
lucky x = "Bad luck" 

私はlucky.hsとしてこれを保存し、インタプリタでそれを実行し、それが正常に動作します。

しかし、私は関数定義については不明です。それは私が次のように私は同じように機能ラッキー定義することができることを読んだことがほとんどないかららしい(関数名はlucky2です):

lucky2::(Integral a)=> a-> String 
lucky2 x=(if x== 7 then "LUCKY NUMBER 7" else "Bad luck") 

はどちらも同じようにうまく動作するように見えます。明確に機能する幸運は明確に読み取るが、lucky2関数を書く正しい方法ですか?

+4

私が知る限り、彼らは意味は同じですが、最初のものはよりよく見え、ハスケルでそれをするのが好ましい方法です。私はハスケルの熟達者ではなく、間違っているかもしれないので、これを答えとして掲示しません。 – Matej

+0

ところで、括弧は必要ありません: 'lucky2 x = = x == 7ならば" LUCKY NUMBER 7 "else" Bad luck "' – sdcvvc

+0

また、 'lucky :: Integral - > String' 。 '=>'の左にある命名は、同じ型を2回必要とする場合にのみ当てはまります。 –

答えて

14

どちらも正しいです。おそらく、最初のものは、のパターンマッチングという非常に重要な機能を使用しているので、より慣用的なハスケルです。この形式では、それは通常のように書くことになります。

lucky::(Integral a)=> a-> String 
lucky 7 = "LUCKY NUMBER 7" 
lucky _ = "Bad luck" 

アンダースコアは、あなたのパラメータの正確な形式(値)を無視しているという事実を意味します。以前の宣言でキャプチャされたパターンである7とは違うだけです。


パターンマッチングの重要性は、リストなどのより複雑なデータを処理する機能によって最もよく説明されています。あなたは、リストの長さを計算する関数を記述した場合、たとえば、あなたはおそらく、空のリストのバリアントを提供することから始めます:

len [] = 0 

[]句は空のリストと一致するように設定されている模様であり、 。空のリストは明らかに長さが0なので、関数が返すものです。

lenの他の部分は次のようになります。

ここ
len (x:xs) = 1 + len xs 

、あなたはパターン(x:xs)に一致しています。大腸菌:は、いわゆる小文字の演算子です:リストに値を追加しています。したがって、表現x:xsは、いくつかの要素(x)がいくつかのリスト(xs)に追加されたパターンに一致します。 xsは空リスト([])でもかまいませんので、全体として、少なくとも1つの要素を持つリストと一致します。

lenのこの第2の定義もかなり簡単です。残りのリスト(len xs)の長さを計算し、最初の要素(x)に対応する1にします。

(上記の定義を書くための通常の方法は次のようになります。もう一度あなたはそれが存在することのみが、最初の要素が何であるかを気にしないことを意味し

len (_:xs) = 1 + len xs 

)。これは警備員を使用することになり書き込みに

+0

残念ながら、リストの長さを計算するための悪い方法を示しています。 – Ingo

+5

Ingo、wut?さえもstd。ライブラリはこのようにします:[genericLength](http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#genericLength)。 'Int'やその他のタイプの最適化を行うこともできますが(' strictGenericLength'を参照)、漸近的な時間要件を変更することさえありません。 – Rotsor

7

第三の方法:

lucky n 
    | n == 7 = "lucky" 
    | otherwise = "unlucky" 

ことについて混同しない理由はありません。それには常に1つ以上の方法があります。パターンマッチやガードがなくてもがあり、ifを使用していても、これは当てはまります。

これまで説明したフォームのすべては、Haskellによって提供されたの構文的な砂糖を使用しています。パターンガードは、通常のcase式だけでなく、複数のfunction句とif式に変換されます。従って、最も低レベル、これを書くためunsugared方法は、おそらく次のようになります。

lucky n = case n of 
    7 -> "lucky" 
    _ -> "unlucky" 

あなたが、私は何でも、彼は最高の彼のために働くものは何でも使用することを初心者にお勧めしたい慣用的な方法を確認することは良いですが彼は一番よく理解しています。たとえば、フリースタイルのポイントを(まだ)理解していない場合、それを強制する理由はありません。遅かれ早かれあなたに来るでしょう。

関連する問題