Используя одну неподвижную структуру, мы можем написатьПравильный способ обобщения полей данных на основе перечисленной типа
data Stats = Stats { lines :: !Int, words :: !Int }
instance Num Stats where
fromInteger x = Stats x x
(Stats a b) + (Stats a' b') = Stats (a + a') (b + b')
мы можем создать некоторую динамическую структуру для достижения обобщенной версии
newtype Stats a = Stats { unStats :: [Int] } -- or Map, Vector, ...
instance forall a . (Enum a, Bounded a) => Num (Stats a) where
fromInteger = Stats . replicate sz
where sz = fromEnum (maxBound::a) - fromEnum (minBound::a) + 1
(Stats a) + (Stats b) = Stats $ zipWith (+) a b
(¨) :: forall a . (Eq a, Enum a, Bounded a) => Int -> a -> Stats a
x ¨ u = Stats $ map (\k -> if k == u then x else 0) [minBound .. maxBound :: a]
и использовать в качестве
data TextStats = Lines | Words deriving (Eq, Ord, Enum, Bounded)
someTextStats :: Stats TextStats
someTextStats = 1 ¨Lines + 5 ¨Words
прежний способ является статическим (например, функция измерения единиц измерения будет), но а не в том смысле, что определенная структура должна быть пройдена во время выполнения.
Существует какой-то путь от шаблона Haskell? Thk!
Аноним, вы можете объяснить свой -1? – josejuan
Второй анонимный, вы можете объяснить свой -1? – josejuan