LINUX.ORG.RU

Haskell existentiallty quantified types

 


0

4

Любители хаскелла, расскажите мне про них.

Например, я пишу компилятор для такого языка:

data Expr = S String
          | I Int
          | D Double
          | Plus Expr Expr
          | Minus Expr Expr

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

Вот я пишу eval:

eval :: Expr -> Expr
eval (Plus e1 e2) = evalBinaryOp (+) e1 e2
eval (Minus e1 e2) = evalBinaryOp (-) e1 e2
eval e = e 

где

evalBinaryOp :: Num a => (a -> a -> a) -> Expr -> Expr -> Expr
evalBinaryOp op expr1 expr2 = case (eval expr1, eval expr2) of
                                (D d1, e2) -> let d2 = toDouble e2
                                              in D (op d1 d2)
                                (e1, D d2) -> let d1 = toDouble e1
                                              in D (op d1 d2)
                                (I i1, e2) -> let i2 = toInt e2
                                              in I (op i1 i2)
                                (e1, I i2) -> let i1 = toInt e1
                                              in I (op i1 i2)
                                _ -> I 0
  
toDouble :: Expr -> Double
toInt :: Expr -> Int

В этом коде проблема: фунция op не полиморфна. Как мне изменить тип evalBinaryOp чтобы она стала полиморфной как (+)? Я плохо понимаю forall, расскажите кто разобрался.


Работает с

evalBinaryOp :: (forall . Num a => a -> a -> a) -> Expr -> Expr -> Expr

не работает с

evalBinaryOp :: forall . Num a => (a -> a -> a) -> Expr -> Expr -> Expr

объясните мне в чем разница

nokachi
() автор топика
Ответ на: комментарий от nokachi

1. Existential quantification здесь ни при чем, это обычные rank-2 types.

2. В первую функцию пользователь обязан первым аргументом отгрузить полиморфную функцию, во вторую может инстанцировать для Int, например.

anonymous
()
Ответ на: комментарий от anonymous

спасибо за поинтер, попробую дальше сам

nokachi
() автор топика
Ответ на: комментарий от fmap

спасибо, этот талмуд у меня уже есть, собираюсь его читать

nokachi
() автор топика
Ответ на: комментарий от dmitry_malikov

Там же русским по белому написано о чем она...

fmap
()
Ответ на: комментарий от anonymous

1. Existential quantification здесь ни при чем, это обычные rank-2 types.

Existential quantification это и есть обычные rank-2 types.

anonymous
()
Ответ на: комментарий от anonymous

Не совсем так. Сами по себе existentially qualified типы вполне rank-1:

f :: exists a. a -> a
f () = ()

Конкретная реализация (GHC), предпочитает выводить exists через forall (exists a. a ~ forall r. (forall a. a -> r) -> r), что эквивалетно, но rank-2.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.