Alexandr
ничего не понял, то все не так
Ну тип, у нас есть
class Foo a where bar :: a -> Bool
Мы можем создать инстанс для Int
instance Foo Int where ...
Но наприме мы хотим инстанс не для Int, а для Num,
мы его сделали и для Int работает функция bar,
потом делаем
newtype Int' = Int' Int deriving (Foo) и это перестает работать
Alexandr
используя GeneralizedNewtypeDeriving конечно
Alexander
не понимаю, что такое instance для Num
Sherzod
Видеолекция Хаскель - Монады 5 часов. Это нормально?
Alexander
если мы сделали instance для Num, то очевидно, что надо писать:
newtype Int' = Int' Int deriving (Num)
Dmitry
курс на степике нормально
Dmitry
только это не ютуб
Alexandr
я новичек, точно могу ошибаться в названиях:) Я имел ввиду, что мы создаем instance для Int
instance Foo Int where bar ...
Но почему бы того же делать не для типов, а для тайпклассов
Alexander
тут одновременно 4 вопроса и вечно в них путаница
parket
Alexander
можно:
a. реализовать для всех типов с констрейном Num, но для других нельзя:
instance Num a => Foo a
Alexander
можно сделать дефолтную реализацию для Num:
class Foo a where
default bar :: (Num a, Ord a) => ...
Alexander
тогда если у типа есть Num, то достаточно будет написать: instance Foo A
Alexander
делается инстанс класса для типа
Alexander
конечно никто наверное не запрещает сделать:
class Foo (a :: * -> Constraint) where
Alexandr
Alexander
и реализовывать классы для классов =)
Alexander
/shrug
Alexander
я не вижу ни кода ни ошибки компиляции, я ничего сказать не могу
Vasiliy
Alexander
{-# LANGUAGE DefaultSignatures #-}
class Foo a where
foo :: a -> Bool
default foo :: (Ord a, Num a) => a -> Bool
foo x = x > 5
instance Foo Int
Alexander
эта часть точно работает
Alexander
что там дальше происходило я не знаю
Alexandr
Да, сори, сработало, видимо как-то криво сам написал. Просто идея была в том, чтобы не писать интанс для каждого типа, который принадлежит какому-то тайпклассу
Alexander
не надо так
Alexander
у если захочется написать свой инстанс для класса, у которого есть такой констрейнт, то у компилятора не будет причин предпочитать тот или иной
Alexandr
Alexander
ты можешь написать:
instance (Ord a, Num a) => Foo a where
Alexandr
Alexander
так?
Alexandr
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
class Foo a where
foo :: a -> Bool
class Bar a where
bar :: a -> Bool
newtype Int' = Int' Int deriving (Eq, Ord, Num)
instance (Ord a, Num a) => Foo a where
foo n = n > 5
instance (Ord a, Num a) => Bar a where
bar n = n > 10
Alexander
вот, это инстанс для всех типов а
Alexander
т.е. любой вообще любой тип под него попадает
Alexander
совсем любой
Alexander
после того как инстанс выбран компилятор смотрет в констрейнты
Alexander
и или падает или выбирает
Alexander
через overloading можно сначала делать конкретные потом остальные, но это так себе путь
Vasiliy
overloading - имеется в виду overlaps и overlapping ?
Alexander
да
Alexander
отвлекаюсь
Alexandr
просто не совсем понимаю чем это плохо
Alexandr
оно же так и работает
Alexander
> если захочется написать свой инстанс для класса, у которого есть такой констрейнт, то у компилятора не будет причин предпочитать тот или иной
Alexandr
ну я понял, короче это будет работать и будет вроде удобно, пока не перестанет :D
Vasiliy
оно перестанет работать при появлении любого другого инстанса Foo
Vasiliy
и предложит пошаманить прагмами OVERLAPS и OVERLAPPABLE
Vasiliy
я не знаю, какие конкретно проблемы оно за собой тянет, но знающие люди говорят, что лучше с этой фигнёй не связываться
Alexandr
понял, спасибо за разъяснение:)
Alexander
ну OVERLAPS и OVERLAPPABLE сделало жизнь гораздо лучше
Alexander
чем было до
Alexander
но все равно есть шансы оказаться одновременно с двумя разными словарями
Alexandr
Я кстати посмотрел доку ghc, там поиска нет, как можно найти раздел с прагмами?
Alexandr
или мб есть дока с нормальным поиском?
Kirill
Alexander
@basov_ae https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/lang.html
Alexander
аккуратный overlappable/overlapping норм
Vladislav
Но в случае конечного множества опций лучше closed type family и вспомогательный класс
Vladislav
Потому что тогда аккуратничать не придется
Vasiliy
> лучше closed type family и вспомогательный класс
а есть конкретный пример?
Vladislav
См. RElem с вспомогательным параметром в vinyl
Vladislav
Где-то был еще классный gist от IcelandJack на этот счет
Vasiliy
спасибо, погуглю
Alexander
а можно по олеговски MPTC+FD
Alexander
но суть там будет примерно та же
Alexandr
Ребят, как можно написать map используя fold? Когда есть
data Tree a = Leaf | Node (Tree a) a (Tree a)
fold :: (a -> b -> b) -> b -> Tree a -> b
Alexandr
с фолдом с 3-мя аргументами все понятно, а вот что с двумя делать воообще понять не могу
Alexandr
map :: (a -> b) -> Tree a -> Tree b
Vladislav
а fold в in-order обходит дерево, или как?
Vladislav
и нужно ли сохранять структуру оригинального дерева?
Alexandr
в этом фолде постордер выходит, как сделать инордер не понял для функции с двумя параметрами. Сохранить порядок было бы логично, но как это сделать как раз и не понимаю
foo
Vladislav
Alexandr
Да, я тоже думал об этом, но подумал, что может я чего-то не вижу
Alexandr
В книге задание такое
Aleksei (astynax)
Сохранить порядок нельзя, т.к. оный никак не передается в функцию a -> b -> b, сл-но восстановить структуру не из чего.
Cheese
Sherzod
Кто-то уже звонил ему?
Dmitry
это не друг, это мир, где он коллега
Dmitry
что-то тут странное
Sherzod
Маркетолог от БолгенОС