10

部分的に適用された関数を渡しています。完全な署名は次のとおりです。

import Data.Map as Map 
-- Update the correct bin of the histogram based on the min value, bin width,
-- the histogram stored as a map, and the actual value we are interested in.
updateHist :: Double -> Double -> Map.Map Bin Double -> Double -> 
              Map.Map Bin Double

この関数は、ヒストグラムのデータを格納する Map を更新します。最初の 2 つのパラメーターは、関心のあるデータの下限を示し、次はヒストグラムのビン幅です。プログラムの起動時にこれらの値を入力し、部分的に適用された関数をモジュール全体に渡します。これは、次のような署名を持つ関数がたくさんあることを意味します。

-- Extra the data out of the string and update the histogram (in the Map) with it.
doSomething :: String -> (Map.Map Bin Double -> Double -> Map.Map Bin Double) -> 
               Map.Map Bin Double

これはすべてうまくいきますが、「(Map.Map Bin Double -> Double -> Map.Map Bin Double)」と書くのはかなり冗長です。それらをすべてタイプとして「UpdateHistFunc」に置き換えたいのですが、何らかの理由で失敗し続けます。

私は試した:

newtype UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double

これはエラーで失敗しました:

HistogramForColumn.hs:84:44: 入力 `->' の解析エラー

私は何を間違っていますか?

4

1 に答える 1

17

ここで混乱typeしてnewtypeいますか?

Usingtypeは型シノニムを定義しますが、これはあなたがやろうとしているように見えますがnewtype、 with のようにコンストラクター名を必要とする新しい型を作成しdataます。

言い換えれば、おそらくこれが必要です:

type UpdateHistFunc = Map.Map Bin Double -> Double -> Map.Map Bin Double

...または多分これ:

newtype UpdateHistFunc = UpdateHistFunc (Map.Map Bin Double -> Double -> Map.Map Bin Double)

後者は、関数を適用するために明らかに「ラップ解除」する必要があります。


参考のため:

  • data新しい代数データ型を定義します。これは、再帰的であり、型クラスの個別のインスタンスを持ち、可能な遅延の追加レイヤーを導入するなど、すべてのものです。
  • newtype単一の引数をとる単一のコンストラクターでデータ型を定義します。これは再帰的であり、個別のインスタンスを持つことができますが、型チェックの場合のみです。コンパイル後は、含まれている型と同等です。
  • type型シノニムを定義します。これは、再帰的または個別のインスタンスを持つことができず、型チェック時に完全に展開され、マクロにすぎません。

「余分な怠惰」が関係する と のdata間のセマンティックな違いについて疑問に思っている場合は、これら 2 つのタイプと、それらが持つことができる値を比較してください。newtype

data DType = DCon DType

newtype NType = NCon NType

undefinedたとえば、これらの関数をvs.DCon undefinedNCon undefinedにそれぞれ適用するとどうなると思いますか?

fd (DCon x) = x
fn (NCon x) = x
于 2011-06-17T21:40:46.823 に答える