
Aleksey
21.04.2018
05:00:57
Проблема в конкретном пересечении Num a и Zp a => Num a

Kit
21.04.2018
05:01:34
первый код я так и написал, но мне захотелось использовать + вместо <+>

Даниил
21.04.2018
05:02:16

Aleksey
21.04.2018
05:02:23
newtype же решит проблему, не?
можно будет писать 1 + 2 * 3 и подразумевать Zpable Int, например

Google

Aleksey
21.04.2018
05:03:16
Тут как раз помогает fromInteger - числовые литералы "апгрейдятся" до типа-обёртки

Kit
21.04.2018
05:04:30
пока не понимаю, для меня 'newtype = data'

Aleksey
21.04.2018
05:05:10
newtype это "как data", но выкидывается компилятором после проверки типов

Даниил
21.04.2018
05:05:13

Kit
21.04.2018
05:05:53
тэкс, а куда ее навешивать?
класс Zp сделать newtype ?

Aleksey
21.04.2018
05:06:26
Я же выше "рыбу" написал :)
Нужно завести тонкую обёртку
class Zp a where
...
newtype Zpable a = Zpable a
instance Zp (Zpable Int) where
...
instance Num (Zpable a) where
...
Класс остаётся тем же

Kit
21.04.2018
05:06:58

Aleksey
21.04.2018
05:07:00
Просто инстансы Zp пишутся не для Int, а для Zpable Int

Kit
21.04.2018
05:07:31

Даниил
21.04.2018
05:08:04
класс Zp сделать newtype ?
у тебя видимо немного путаница между типами и классами типов в голове)
newtype (как и data) — это создание нового типа, а не класса

Google

Aleksey
21.04.2018
05:08:30
Да ладно, это сложно с непривычки. Все путаются

Kit
21.04.2018
05:08:38

Даниил
21.04.2018
05:08:49

Kit
21.04.2018
05:09:03
:)

Даниил
21.04.2018
05:09:16
я ж без наезда
я вообще самый нетоксичный человек в русскоязычном коммьюнити!

Kit
21.04.2018
05:09:32
поэтому удивляюсь тому как я понял некоторые вещи :)

Aleksey
21.04.2018
05:10:39
Классы обычно не участвуют в описании типа, точнее для них есть особое место - место для указания ограничений
И нельзя писать f :: Num a
Но можно f :: Num a => a
Классы, это как-бы свойства типа. И мы пишем не
f :: Зелёноё, а
f :: что-то (но что-то зелёное) :)
Человек то умный, он может из первого вывести второе. А компилятор пока не готов к такому - ему нужно, чтобы был объект, пусть даже и со свойствами :)
(ща набегут - как проснутся - и напишут, что я в корне неправ)

Kit
21.04.2018
05:16:05


Даниил
21.04.2018
05:16:15
@newrlan на счёт ньютайпов, чтобы было немного понятнее, вот такой отвлечённый пример
есть класс моноид
и допустим те же целые числа являются одновременно моноидом и по сложению (с нейтральным нулём), и по умножению (с нейтральной единицей)
но два инстанса Monoid для одного типа Int мы конечно сделать не можем
но мы можем завести две обёртки:
newtype IntAddMonoid = IntAddMonoid Int
newtype IntMulMonoid = IntMulMonoid Int
и написать разные реализации тайпкласса Monoid для них, и таким образом избежать того что инстансы будут пересекаться
при этом так как это newtype а не data, никакого оверхеда в виде боксинга-анбоксинга в рантайме не будет (то есть в рантайме это будет просто Int, без всяких обёрток) + емнип там автодерайвятся всякие Coercible чтобы удобно было туда-сюда преобразовывать Int в IntAddMonoid/IntMulMonoid и обратно

Aleksey
21.04.2018
05:16:16
Да

Kit
21.04.2018
05:19:07


Aleksey
21.04.2018
05:21:21
?

Kit
21.04.2018
05:21:43

Google

Kit
21.04.2018
05:21:48
теперь

Aleksey
21.04.2018
05:22:08
Да

Kit
21.04.2018
05:22:34
и это не потребует затрат на лишнюю память?

Aleksey
21.04.2018
05:22:41
Нет :)

Kit
21.04.2018
05:22:45
как на новую структуру данных?

Aleksey
21.04.2018
05:23:04
При компиляции newtype выкидывается. Т.е. никакого заворачивания/разворачивания не будет

Kit
21.04.2018
05:23:59
Это круто!

Aleksey
21.04.2018
05:24:10
Нам тоже нравится :)

Kit
21.04.2018
05:24:49
А можно еще один вопрос?

Aleksey
21.04.2018
05:25:05
Можно :)

Kit
21.04.2018
05:26:01
я вот определил Num на Zpable, но я стремлюсь определить Fractional на Zpable
придется и на Num и на Fractional прописывать инстанс

Kit
21.04.2018
05:26:44
или можно как-то это все в одну кучу собрать?

Alexander
21.04.2018
05:29:16
нужно прописать инстансы для всех классов, может помочь расширение GeneralizedNewtypeDeriving
GND работает так: разворачивает newtype, применяет инстанс базового типа и заворачивается обратно

Aleksey
21.04.2018
05:32:14
Num нельзя дерайвить, т.к. поведение зависит от инстанса Zp. Остальное можно, думается

Kit
21.04.2018
05:34:47
вот теперь я хочу объявить тип пусть называется Zp61 как мне сказать что этот тип Zpable ?
я хочу прописать instance Zp Zp61 where
но я так понимаю, что мне нужно что бы Zp61 был типом Zpable (вот тут я уже поплыл)

Aleksey
21.04.2018
05:41:53
Не, Zpable нужет только для оборачивания существующих типов - Integer, Float, и т.п.

Google

Aleksey
21.04.2018
05:42:31
Если есть кастомный тип, то для него инстансы можно писать, не оборачивая предварительно в Zpable

Kit
21.04.2018
05:43:07
а как тогда написать instance Zp a => Num a ибо компилятор ругается

Aleksey
21.04.2018
05:43:29
А зачем такой инстанс писать то?
Для Zp61 инстанс будет instance Num Zp61 where

Kit
21.04.2018
05:44:11
ну у меня условно 100500 костомных типов, самое главное все они Zp
поэтому ввел Zp

Aleksey
21.04.2018
05:45:49
Тогда много конкретных инстансов
instance Zp (Zpable Zp61)
плюс один обобщённый
instance Zp (Zpable a) => Num (Zpable a)
И все значения заворачивать в Zpable (или использовать численные литералы)

Alexander
21.04.2018
05:46:57

Admin
ERROR: S client not available

Kit
21.04.2018
05:47:45

Alexander
21.04.2018
05:47:50
можно сделать newtype Zp (n::Nat) = Zp Int
если 61 это модуль или что там из групп
тогда написать инстанс для всего в соответствии с этим n
и потом делать 1 :: Zp 35

Kit
21.04.2018
05:50:11

Alexander
21.04.2018
05:50:41
в n ?

Kit
21.04.2018
05:50:46
да

Google

Alexander
21.04.2018
05:50:56
Nat ~ Integer но только положительные

Kit
21.04.2018
05:50:57
я думал нельзя константы совать в объявления типов

Alexander
21.04.2018
05:51:22
для отрицательных наверное надо будет Bool добавить чтобы вся машинерия работала
в GHC.TypeLits есть кусок докумертации
вообще это DataKinds + доп машинерия в ghc для того чтобы литералы можно было поднимать
последнее для строк и натов есть
но они не индуктивные будут
для задачи наверное это и не нужно
ghc пока ещё не идеально со всей этой машинерией работает, но если не нужно будет много вычислений на n то прокатит

Kit
21.04.2018
05:54:07

Alexander
21.04.2018
05:54:23
я к сожалению до ноутбука только к вечеру доберусь, так что полностью готовый пример со ссылками на релевантные статьи только вечером смогу сделать
ну если на *тайплевел* термах будут всякие вычисления то там нужно очень следить за структурой чтобы доказать верность
использование самих Zp не ограничивается
просто если будет foo :: Zp n -> Zp m -> Zp (сложная формула от n m)
то тайпчеккеру может плохо стать
особенно если рядом будет другая сложная формула, которая сводится к тому же результату
например доказать что Min n m = Min m n будет нетривиально
есть пакет от кметта с аксиомами и плагин, но я схожу не помню
в любом случае задачу это покрывать хорошо должно
в модуле GHC.TypeLits есть всё для прыжков между type и value level

Yuriy
21.04.2018
09:51:40
есть какой-нибудь готовый тайпкласс или математический термин, обозначающий особое "пустое" значение?
например, Nothing для Maybe
точнее, мне надо обобщить Nothing и '\NUL'
семантика — отсутствие значения

kana
21.04.2018
10:05:14
наверное его можно назвать терминальным, но я не уверен
а если его можно назвать еще и инициальным, то есть термин "нулевой"