2017-11-17 11 views
7

私はそれが現在"name" = Int - 宣言する価値はありますか?機能は、私が思った</p> <pre><code>priceOfProduct :: Int -> Int -> Price ? </code></pre> <p>なるよう

priceOfProduct:: Int -> Int -> Int 

のように見える、製品の価格を返す関数を持っているが、それは

type Price = Int 

を宣言する価値がありますこれを行うには、次に私たちがIntsのタプルを使用するようにしていきます。それは、それが独自のデータ構造であれば、もっと良く見えるでしょう。

priceVsTaxed -> Price -> Int -> (Price, Price) 

これは役に立ちますか?これは必要ですか?

この良いハスケルスタイルですか?

既存のデータ構造の正しいスタイルの名前を変更するように見えるデータ構造を宣言していますか?

+1

'Int - > Int - > Price'は、関数の名前が既に価格を強く意味しているので、役に立たない。 'type Quantity = Int'と' UnitPrice = Int'を入力すると、より便利な 'priceOfProduct :: Quantity - > UnitPrice - > Price'が可能になります。 – chepner

+0

これは、最後に収まるかどうか不明な場合に備えて、タイプを変更する簡単な方法です。 –

答えて

11

余分な型を定義する価値はありませんが、Int -> ... -> Intシグネチャは絶対に避けてください。これらは、関数の使用方法を理解することを非常に困難にします。

実際、私はおそらく結果だけでなく、とりわけ引数の名前を変更するべきだと言います。誰かがあなたの関数を使用したい場合はその後、彼らは、コンパイラが引数を説明してみましょうことができます。

foo :: Price 
foo = priceOfProduct _ _ + priceOfProduct _ _ 

は、コンパイラにあなたがしかし考慮しなければならない

Foo.hs:Y:X: error: 
    • Found hole: _ :: PriceOfProductFirstArgument 
    • In the first argument of ‘priceOfProduct’, namely ‘_’ 
     In the expression: priceOfProduct _ _ 
     In an equation for ‘foo’: main = foo = priceOfProduct _ _ + priceOfProduct _ _ 

のような(GHC> = 7.10)メッセージを表示しますあなたはタイプの区別はより剛性したくない場合は:シンプルtype DEFが間違った順序で引数を入れてからあなたを救うことはできませんので、おそらくあなたは改善するだろう、それ

newtype Price = Price {priceInEuroCents :: Int} 

これはまた、価格が与えられる通貨/数量の曖昧さを回避します。

+1

最後の 'newtype':' newtype Price u = Price {getPrice :: Int} 'に' data Euro'、 'data USDollar'を少し追加すると、異なる通貨で' Price'関数を再利用することができます。 – Zeta

+1

@Zetaこれは現実の金融アプリケーションにとってはおそらく正しいことです(換算は同形ではありません)。そのようなデータ型は、具体的な単位システムへの参照なしに、その量の一般的な物理的概念をIMOで抽象化する必要があります。 – leftaroundabout