我有一堆函数,例如:
所以用户可以像这样调用它们:
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")
。
据我所见,有两个选项:
Massive
data
construction and massive unpack function: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
Lots of code.
Common typeclass and newtypes:
EDIT: Okay then, we can useGeneralizedNewtypeDeriving
in such simple case.{-# 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 ...
Looks much better but all
fk
would look likefk a b ... z = g [("a", unpack a), ("b", unpack b), ... ("z", unpack z)]
Lots of code and duplication.
fk a b ... z = g [("a", a), ("b", b), ... ("z", z)]
g = h . map (second unpack)