169 похожих чатов

Как доказать компилятору, что (Num a) точно будет, потому что

нет других конструкторов, не записывая это в констрейнты foo?

data A a where
MkA :: Num a => {value :: a} -> A a
foo :: A a -> A a -> A a
foo a b = MkA (value a + value b)

==============================
error:
• No instance for (Num a) arising from a use of ‘MkA’
Possible fix:
add (Num a) to the context of
the type signature for:
foo :: forall a. A a -> A a -> A a
• In the expression: MkA (value a + value b)
In an equation for ‘foo’: foo a b = MkA (value a + value b)

foo a b = MkA (value a + value b)
^^^^^^^^^^^^^^^^^^^^^^^

11 ответов

15 просмотров

Просто не задавать тип для foo. Компилятор как раз знает, что тип будет Num a => A a -> A a -> A a, поэтому ругается на неправильную сигнатуру.

Максим-Б Автор вопроса
Михаил
Просто не задавать тип для foo. Компилятор как раз...

а если усложнить задачу? :) тут сигнатуру убрать нельзя, она в классе написана class C c where foo :: a -> c a data A a where MkA :: Num a => a -> A a instance C A where foo a = MkA a =========================== a.hs:40:13: error: • No instance for (Num a) arising from a use of ‘MkA’ Possible fix: add (Num a) to the context of the type signature for: foo :: forall a. a -> A a • In the expression: MkA a In an equation for ‘foo’: foo a = MkA a In the instance declaration for ‘C A’ | 40 | foo a = MkA a |

Максим Б
а если усложнить задачу? :) тут сигнатуру убрать н...

Тут это уже не работает специально. foo в том виде, в каком вы её описали, должна работать для любого типа, а в случае MkA это не так. Решений два: или добавить Num a в сигнатуру foo, или убрать Num a из определения типа A (действительно ли он там нужен?). Может быть, меня кто-то поправит, указав ещё пути.

Максим-Б Автор вопроса
Михаил
Тут это уже не работает специально. foo в том виде...

я колдую над чуть более сложным примером, там констрейнт для конструктора убрать не получится, имплементация на него завязана при этом у разных типов, для которых я хочу инстансы класса, эти констрейнты разные то есть хочется что-нибудь вроде instance Num a => C (A a) where ... но "a", как здесь, зафиксировать (так можно сказать?) нельзя, потому что тогда по кайндам не проходит - C хочет "* -> *", а у "A a" он просто "*"

Максим Б
я колдую над чуть более сложным примером, там конс...

В этом случае надо изменить foo. Всё-таки ограничения важны в типах, они не для красоты пишутся. Думаю, можно ещё как-то поколдовать с TypeFamilies или MultiParamTypeClasses, чтобы вынести задание Num в другую часть кода. Что-то вроде class Num a => C c a where foo :: a -> c a

Максим Б
посмотрю, спасибо!

{-# LANGUAGE GADTs, MultiParamTypeClasses, FlexibleInstances #-} class C c a where foo :: a -> c a data A a where MkA :: Num a => a -> A a instance Num a => C A a where foo = MkA Но меня всё равно не оставляет ощущение, что проще было бы добавить Num a как ограничение к foo или разобраться, что же на самом деле требуется для A.

Максим-Б Автор вопроса
Михаил
{-# LANGUAGE GADTs, MultiParamTypeClasses, Flexibl...

проще в конкретном случае - конечно :) но может быть, например, библиотечный класс, который менять нельзя интересно разобраться, как такие штуки вообще решают (я ж точно не первый, кто таким вопросом задался) за сниппет спасибо! буду разбираться :)

Максим Б
проще в конкретном случае - конечно :) но может бы...

Там ещё есть хитрость. Или такой класс: class C con c | c -> con where foo :: con a => a -> c a И сделать instance C Num A С типами аналогично. Можно, например, написать: data A n a where MkA :: n a => a -> A n a Правда, в обоих случаях надо не забыть включить нужные расширения.

Максим-Б Автор вопроса
Михаил
Там ещё есть хитрость. Или такой класс: class C co...

вау, втащить констрейнты в параметры я б точно не догадался спасибо огромное!

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта