У меня есть куча функций, как:Haskell - обертки типа объединительных
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
участки кода.
Общие и Newtypes класс типов:
EDIT: Хорошо, мы можем использовать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)