Как перейти от кортежей к пользовательскому типу данных? - PullRequest
1 голос
/ 10 мая 2019

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

Тип данных

data Expr = Num Int | Bop Expr Op Expr  deriving  (Eq,Show)

и функция должна иметь эту подпись

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr

inExpr должно быть, я думаю, что-то вроде

inExpr = Either Num (Bop something)

но я не могу понять что-то.

Ответы [ 2 ]

9 голосов
/ 10 мая 2019

Почему бы просто не

inExpr ie = case ie of
  Left n -> Num n
  Right (o, (e1, e2)) -> Bop e1 o e2

?

Или, если вам нравится either функция

inExpr = either Num (\(o, (e1, e2)) -> Bop e1 o e2)
6 голосов
/ 10 мая 2019

Вы совсем близко. Фактически мы можем легко получить тип something, используя " hole " (_) в ghci:

Prelude Data.Either> :{
Prelude Data.Either| inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
Prelude Data.Either| inExpr = either Num _
Prelude Data.Either| :}
<interactive>:36:21: error:
    • Found hole: _ :: (Op, (Expr, Expr)) -> Expr
    • In the second argument of ‘either’, namely ‘_’
      In the expression: either Num _
      In an equation for ‘inExpr’: inExpr = either Num _
    • Relevant bindings include
        inExpr :: Either Int (Op, (Expr, Expr)) -> Expr
          (bound at <interactive>:36:1)

Итак, мы знаем, что эта функция _ должна иметь тип (Op, (Expr, Expr)) -> Expr.

Мы можем, например, использовать здесь лямбда-выражение:

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
inExpr = either Num <b>(\(o, (l, r)) -> Bop l o r)</b>

Таким образом, мы «распаковываем» кортеж и поднабор с шаблоном (o, (l, r)), а затем создаем Expr, используя конструктор данных Bop с l, o и r в качестве аргументов .

При этом простое сопоставление с образцом, например, в заголовке функции, также поможет, и, возможно, легче понять:

inExpr :: Either Int (Op,(Expr,Expr)) -> Expr
inExpr (Left a) = Num a
inExpr (Right (o, (l, r))) = Bop l o r
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...