我有这样一组函数:哈斯克尔 - 型包装统一
f1 :: String -> String -> ... -> String ->()
f1 a b ... z = g [("a", a), ("b", b), ... ("z", z)]
...
fn :: String -> Int -> String -> ... -> String ->()
fn a b ... z = g [("a", a), ("b", show b), ... ("z", z)]
所以用户可以叫他们像f1 "abc" "def"
。我不希望他这样做,因为他可以轻松地交换“abc”和“def”(并且上帝知道调试时会浪费多少时间)。我希望他来传递参数一样fk (A "abc") (B "def")
据我所看到的,有2个选项:
大规模
data
建设和大规模的解压功能:data Value = A String | B String | C Int | D String ... unpack :: Value -> String unpack (A a) = a unpack (B b) = b unpack (C c) = show c unpack (D c) = d
大量的代码。
常见的类型和新类型:
编辑:好的,那么,我们可以在这种简单的情况下使用GeneralizedNewtypeDeriving
。{-# LANGUAGE GeneralizedNewtypeDeriving #-} class Value a where unpack :: a -> String instance Value String where unpack = id instance Value Int where unpack = show newtype A = A String deriving Value newtype B = B String deriving Value newtype C = C Int deriving Value newtype D = D String deriving Value ...
看起来好多了,但所有
fk
会是什么样子fk a b ... z = g [("a", unpack a), ("b", unpack b), ... ("z", unpack z)]
大量的代码和重复。
我想要的是一些魔术这将让我:
fk a b ... z = g [("a", a), ("b", b), ... ("z", z)]
g = h . map (second unpack)