Хранение полей типа в списке - PullRequest
0 голосов
/ 03 июля 2018

Здравствуйте, я столкнулся со следующей проблемой. У меня есть тип данных с несколькими полями. Мне нужно перечислить их и сохранить в коллекции для дальнейшего сопоставления.

data Worker=Worker{
        age::Int,
        name::String,
        title::Title,
        income::Int
    }


    data Title=Manager | Dev | Tester deriving (Show)



    instance Show Worker where 
        show w=let !names=["age","name", "title","income"] 
                   !props= [age,name,title,income]  in   -- Do i need to define another new type to be able to flat them down to a list?
            "{"++intercalate "," (zipWith (\x y-> x++":"++ y w) names props)++"}"

Где я могу хранить все все свойства (методы), чтобы иметь возможность в дальнейшем использовать их как параметр в функции более высокого порядка для данной переменной типа Worker в нашем случае.

1 Ответ

0 голосов
/ 03 июля 2018

Вы можете приблизиться к тому, что ищете, но это не будет красиво.

Мы можем использовать RecordWildCards, чтобы привести все имена аксессоров в область видимости, как если бы они были обычными переменными, но это все еще создает новую проблему.

-- Not runnable Haskell code
foo Worker {..} = let names = ["age", "name", "title", "income"]
                      props = [age, name, title, income]
                  in ...

Мы сопоставляем шаблон с Worker {..}, который вводит несколько имен аксессоров в локальную область. Однако props пытается быть гетерогенным списком, который Хаскелл не позволяет. Он содержит два целых числа, строку и заголовок, в то время как списки на Haskell должны содержать только один тип.

Поскольку вы пытаетесь показать каждое поле, вам придется применить show к каждому элементу вручную. Как я уже сказал, это будет немного уродливо.

foo Worker {..} = let names = ["age", "name", "title", "income"]
                      props = [show age, show name, show title, show income]
                  in ...

Может показаться, что мы можем сделать map show [age, name, title, income], но мы не можем. Этот список по-прежнему недействителен, и мы применяем здесь три разные функции show (они просто имеют одно и то же имя), поэтому мы не можем осмысленно сопоставить то же самое show с каждый элемент.

Однако, как говорится в комментариях, вам лучше всего ознакомиться с надлежащей библиотекой JSON, и Aeson - лучший выбор в Haskell для такого рода вещей.

...