単純な代数データ(本質的に列挙型)と、フィールドとしてこれらの列挙型を持つ別の型があるとします。ハスケル:代数的データ型に「マッピング」する方法はありますか?
data Color = Red | Green | Blue deriving (Eq, Show, Enum, Ord)
data Width = Thin | Normal | Fat deriving (Eq, Show, Enum, Ord)
data Height = Short | Medium | Tall deriving (Eq, Show, Enum, Ord)
data Object = Object { color :: Colour
, width :: Width
, height :: Height } deriving (Show)
オブジェクトのリストが与えられている場合、属性がすべて異なることをテストしたいと思います。このために、私は(Data.List
からsort
を使用して)機能
allDifferent = comparePairwise . sort
where comparePairwise xs = and $ zipWith (/=) xs (drop 1 xs)
uniqueAttributes :: [Object] -> Bool
uniqueAttributes objects = all [ allDifferent $ map color objects
, allDifferent $ map width objects
, allDifferent $ map height objects ]
を以下しているこれは動作しますが、私は手動で各フィールド(色、幅、高さ)を入力しなければならなかったので、かなり不満です。私の実際のコードでは、より多くのフィールドがあります! 「マッピング」関数Object
のような代数的データ型のフィールドを超える
\field -> allDifferent $ map field objects
の方法はありますか?ここで
スクラップ用の定型文を使用できます。この単純なケースでは、それがはるかに良いかどうかはわかりません。 – chi
ジェネリックでなくても、多少の影響を受けます: 'uniqueAttributes objects = and [go color、go width、go height] go ::(Ord a)=>(Object - > a) - > Bool; go f = allDifferent(マップfオブジェクト) ' –