Имбирь - твой спиритический овощ. Войти !bnw Сегодня Клубы
Поясните для тупых короч Дано: data Req = A | B data Resp = Ra | Rb | Rc Куда нажать, чтобы можно было писать только функции A -> Ra, B -> Rb, B -> Rc, а A -> Rb и A -> Rc было писать нельзя?
#LKLGJP / @plhk / 3657 дней назад

В гугл на первые 3 ссылки по запросу "Haskell GADT"
#LKLGJP/ZCH / @qnikst / 3656 дней назад
@qnikst data TA data TB data Req where A :: Req TA B :: Req TB data Resp where Ra :: Resp TA Rb :: Resp TB Rc :: Resp TB Но в жизни все сложнее и если хочешь разобраться то читай статьи по session types.
#LKLGJP/P6J / @qnikst --> #LKLGJP/ZCH / 3656 дней назад
@qnikst >We describe an implementation of session types in Haskell. Session types statically enforce that client-server communication proceeds according to protocols. Exactly what i want! Спасибо!
#LKLGJP/AC3 / @plhk --> #LKLGJP/P6J / 3656 дней назад
@plhk но это сложно :) чаще хватает решения проще
#LKLGJP/Q6Y / @qnikst --> #LKLGJP/AC3 / 3656 дней назад
@qnikst я уже заметил без пол-пирса не разберешься
#LKLGJP/B24 / @plhk --> #LKLGJP/Q6Y / 3656 дней назад
@plhk Session types почти всегда оверкил, особенно если не хочешь зашивать действительно сложную логику с циклами и условиями. Из неполных решений что я видел это: а. отсутствие решения, б. вместо АДТ под все запросы АДТ под каждый запрос ответ и дальше или тайпкласс или заворачивание в АДТ/ГАДТ. Четкого рецепта подсказать не могу у всего есть плюсы и минусы.
#LKLGJP/0IZ / @qnikst --> #LKLGJP/B24 / 3656 дней назад
Набросал, сам не понимая что делаю: https://gist.github.com/k-bx/d0319a4bc0054516ab17
#LKLGJP/1KR / @kb / 3656 дней назад
@kb Не не не Девид Блейн.. Ты или data R = A | B используй или втыкай type family M Rep Resp :: () where M A RA = () M B Rb = () M B Rc = () protocol :: (Matches a b) => Req a -> (Resp b -> c)
#LKLGJP/UU6 / @qnikst --> #LKLGJP/1KR / 3656 дней назад
@qnikst Уау, круто. Не знал, что можно `(Matches a b) =>` на семействах типов делать, спасибо. Подобное сделано, только на тайп-классах, в Riak-библиотеке (то ли в протобуфах, не помню).
#LKLGJP/6GX / @kb --> #LKLGJP/UU6 / 3656 дней назад
@kb Да, на тайпклассах было чот в протобуфовом интерфейсе к БД какой-то. Но там халява т.к. request однозначно определял reply в итоге все прекрасно сходилось и встраивалось в netwire. Я пытался по образу и подобию сделать чуть более сложный случай и все ломалось к чертям // может не умел тогда просто.
#LKLGJP/JSW / @qnikst --> #LKLGJP/6GX / 3656 дней назад
@qnikst Ну вот это на тайп фемилиес оно и есть, кажется. Или нет? А я же просто сбился и о своих каких-то проблемах начал городить, т.к. у меня еще часто надобность писать что-то, что принимает в параметр только именно `A`, например (и не обязательно возвращает `Ra`). Короче не туда)
#LKLGJP/XNO / @kb --> #LKLGJP/JSW / 3656 дней назад
Справедливости ради, вот запилил пример на тайп-классах, который должен быть понятен начинающему: ``` {-# LANGUAGE MultiParamTypeClasses #-} class Req a instance Req A instance Req B class Resp b instance Resp Ra instance Resp Rb instance Resp Rc class ReqResp a b instance ReqResp A Ra instance ReqResp B Rb data A = A data B = B data Ra = Ra data Rb = Rb data Rc = Rc sendA :: ReqResp a b => a -> b sendA = undefined unSendA :: ReqResp a b => b -> a unSendA = undefined main :: IO () main = do let ra = sendA A :: Ra let a = unSendA ra :: A putStrLn "hello" ``` Как видно, проблема сделать `Req = A | B` встает потому, что `A` и `B` в таком случае имеют один тип. Решается извращениями с DataKinds.
#LKLGJP/IMP / @kb / 3656 дней назад
ipv6 ready BnW для ведрофона BnW на Реформале Викивач Котятки

Цоперайт © 2010-2016 @stiletto.