Зигохистоморфный
Это просто идея)
Зигохистоморфный
Я с телефона)
Aleksei (astynax)
И вообще Either
Aleksei (astynax)
:)
Aleksei (astynax)
f :: Either Text Regex -> ... f (Left text) = ... f (Right regex) = ...
Aleksei (astynax)
Вот так можно "отличить" два типа в функции (только они уже "отличённые" попадут в функцию :))
Андрей
```data Path = Text | Regexp class Match a b where (=~) :: a -> b -> Bool instance Match Route Request where route =~ request = all (\check -> check request) $ allConditions route instance Match Route Path where p =~ Text t = t == p p =~ Regexp r = r =~ p
Aleksei (astynax)
только
Андрей
вот тут матчить как
Aleksei (astynax)
data Path = Text Text | Regexp Regexp
Андрей
только свой тип городить?
Андрей
что-то я не верю
Aleksei (astynax)
request никак из первого параметра не сможет узнать тип второго
Aleksei (astynax)
Впрочем, Functional Dependencies можно использовать
Андрей
поправил свой код, так наверно чуть больше инфы
Aleksei (astynax)
только свой тип городить?
А как ещё сказать компилятору "тут у меня либо T1 либо T2"? Компилятор хочет один конкретный тип. А у нас их два разных. Поэтому нужно оба типа в объединающую обёртку положить - это будет "один тип с ветвлением внутри"
Андрей
типа чтобы отличить один готовый тип от другого нужно написать свой конструктор?
Aleksei (astynax)
Нельзя "отличить один тип от другого". Можно описать такой тип-сумму, который позволит использовать один из двух вложенных в него типов
Aleksei (astynax)
Дело не в конструкторе и в его наличии
Андрей
а в чём?
Андрей
в хаскеле данные матчатся по конструктуру, если я не ошибаюсь
Aleksei (astynax)
Нельзя, даже имея доступ к конструкторам двух разных типов, матчить разные клозы функции по этим конструкторам. Это не перегрузка сишная
Aleksei (astynax)
Данные матчатся по конструкторам одного типа
Андрей
ххмхм
Андрей
странная история
Aleksei (astynax)
Какой тип будет у функции, которая будет матчить по конструкторам разных типов?
Зигохистоморфный
Aleksei (astynax)
Вот вырожденный пример: data Foo = Foo data Bar = Bar f Foo = "foo" f Bar = "bar" Какой тип будет у функции f?
Aleksei (astynax)
@azzaazaa ?
Андрей
у меня другой случай, у меня data Path = Text | Regexp deriving (Eq) то есть в твоём примере нужно ввести тип data Bazz = Foo | Bar тип функции будет тип Bazz -> something какая реализация будет - не знаю, это как раз мой вопрос
кана
Text - конструктор же
кана
не тип
кана
в хаскеле сумма типов - не сумма множеств, а их копроизведение, это как сумма, только помеченая. Text Text как раз текст с меткой Text
Aleksei (astynax)
Нет, у вас всё в порядке с Path. но не в порядке со вторым параметром. Который "либо Text либо Regexp в зависимости от того, что сматчилось в Path"
кана
```data Path = Text | Regexp class Match a b where (=~) :: a -> b -> Bool instance Match Route Request where route =~ request = all (\check -> check request) $ allConditions route instance Match Route Path where p =~ Text t = t == p p =~ Regexp r = r =~ p
ну или я чет не понял, но в этом примере у тебя в деструктуринге у каждой метки есть элементы (t, r), а у самого типа кроме меток нет ничего
Aleksei (astynax)
(=~) :: ? -> Path -> ? -> Bool (=~) p Text t = t == p (=~) p Regexp r = r =~ p
кана
не, у него же не так
Зигохистоморфный
Вот и тут нужны завтипы)
Aleksei (astynax)
не, у него же не так
Я просто переставил местами параметры
Aleksei (astynax)
Ибо меня коробит инфиксная функция трёх параметров :)
кана
x + P y ==> (+) x (P y)
Aleksei (astynax)
Ну ок, вот вам код из примера, только с сигнатурой data Path = Text | Regexp (=~) :: ? -> Path -> ? -> Bool p =~ Text t = t == p p =~ Regexp r = r =~ p
кана
но у него сигнатура другая же)
Aleksei (astynax)
Андрей
Text - конструктор же
вот он кажется прав
кана
из примера его: (~) :: a -> b -> Bool
Андрей
на instance Match Route Path where p =~ t @ Text = t == p p =~ r @ Regexp = rmatch r p компилятор ругается как-то иначе)
Aleksei (astynax)
в коде одно из двух - либо неправильный Path, либо неправильный =~
Андрей
надо только чуть подправить остальной код
кана
в хаскеле сумма типов - не сумма множеств, а их копроизведение, это как сумма, только помеченая. Text Text как раз текст с меткой Text
Aleksei (astynax)
нельзя матчить по разным типам
кана
data Path = Text Text | Regexp Regexp
Aleksei (astynax)
Я это уже предлагал :)
Зигохистоморфный
Ну есть же isLens, isPrism
Зигохистоморфный
Андрей
И я)
выглядит как костылизация)
кана
так нет
кана
у тебя есть уже тип Path
кана
который может быть строкой или роутом
кана
ты даешь им метки, чтобы различать (пусть метка A для Text, B - Route)
Aleksei (astynax)
выглядит как костылизация)
Я же прошу, скажите, как должен выглядеть тип функции, "которая матчит по конструкторам разные типы"?
кана
data Path = A Text | B Route
Aleksei (astynax)
data Path = Text | Regexp - тут Text и Regexp - не типы, это конструкторы одного типа - типа Path
кана
лол
Aleksei (astynax)
some A text = ... _функция двух переметров, а в сигнатуре - один
кана
у меня небольшой диссонанс
Aleksei (astynax)
кароч, кто-то хочет перегрузку по типу в языке, где её нет (к счастью)
кана
у меня небольшой диссонанс
человек использует классы и интерфейсы, решает какую-то реальную проблему (роуты), но выглядит так, будто не понимает, что есть сумма типов в хаскеле. И мне кажется, что это невозможно, поэтому скорее всего я ошибаюсь
Aleksei (astynax)
Чтобы A имело, что разматчить, у конструктора A должен быть параметр - в описании типа. А его там нет
Андрей
Чтобы A имело, что разматчить, у конструктора A должен быть параметр - в описании типа. А его там нет
блин, я свой примером попытался ответить и тебе и тому парню выше)
Андрей
в итоге получилась херня
кана
чтобы он еще хранил текст, нужен аргумент к конструкуру
кана
и тип его Text
Aleksei (astynax)
чтобы можно было матчить f (A foo) = ... нужно, чтобы у A был параметр data T = A foo | ...
Андрей
как я понимаю, что если я где-то описал тип Text, то у него в любом случае есть конструктор, например https://hackage.haskell.org/package/text-1.2.2.2/docs/Data-Text-Internal.html