Size: a a a

2021 July 02

DI

Dmitry Ivanov in Haskell
и парсонс
источник

R

Roman in Haskell
картинка из статьи на лурке про хаскель
источник

DM

Dmitriy Mozhevitin in Haskell
Господа, подскажите пожалуйста:

Имеется игрушечный тайплкасс и пара инстансов

class Cls (name :: Symbol) where
 f :: String

instance {-# OVERLAPPING #-} Cls "" where
 f = "empty symbol"

instance {-# OVERLAPPABLE #-} (KnownSymbol anyName) => Cls anyName where
 f = "any symbol"


при этом

main :: IO ()
main = do
 let s = ""
 let someSymb = someSymbolVal s
 case someSymb of
   (SomeSymbol (p :: Proxy w)) -> putStrLn $ f @w

выдаёт any symbol , а
str :: String
str = f @""

выдаёт empty symbol

я ожидал, что в обоих случаях будет empty symbol
где я заблуждаюсь?
источник

MK

Maxim Koltsov in Haskell
в f @w решение какой инстанс использовать принимается на этапе компиляции, когда ещё неизвестно какой там конкретно символ
источник

MK

Maxim Koltsov in Haskell
инстанс KnownSymbol anyName => Cls anyName подходит там
источник

IO

I O in Haskell
Стоп, а почему не overlapping instances error тогда, оба инстанса же подходят
источник

DB

Danil Berestov in Haskell
Прагмы?
источник

DM

Dmitriy Mozhevitin in Haskell
спасибо, стало ясно
имеется еще пара вопросов тогда:

1) почему
instance {-# OVERLAPPING #-} (KnownSymbol name, name ~ "") => Cls name where
 f = "empty symbol"

instance {-# OVERLAPPABLE #-} (KnownSymbol anyName) => Cls anyName where
 f = "any symbol"


не заводится и ругается на на duplicate instance declarations , хотя чисто интуитивно инстанс для пустого символа и констрейнт на равенство пустой строке должны быть эквивалентны

2) если все-таки очень хочется чтобы для значений, не известных в компайл-тайме, выбирался инстанс с empty symbol , есть ли какие-то воркэраунды?
источник

IO

I O in Haskell
Так не INCOHERENT, а OVERLAPPING же, или я что-то путаю
источник

MK

Maxim Koltsov in Haskell
потому что инстансы выбираются только по части после => (называется instance head)
источник

MK

Maxim Koltsov in Haskell
в твоем случае головы абсолютно одинаковые
источник

MK

Maxim Koltsov in Haskell
по пункту 2 — запихать логику проверки на empty в один инстанс для KnownSymbol name => Cls name
источник

MK

Maxim Koltsov in Haskell
в рантайм, собсно
источник

DB

Danil Berestov in Haskell
источник

IO

I O in Haskell
Насколько я понимаю OVERLAPS/OVERLAPPING решается только когда однозначно понятно, в отличии от инкохерента.

Это, например, дает ошибку

class Foo (x :: Nat) where
 x :: String

instance {-# OVERLAPS #-} Foo 0 where
 x = "zero"

instance {-# OVERLAPPING #-} KnownNat n => Foo n where
 x = show $ natVal $ Proxy @n

foo :: forall n . KnownNat n => String
foo = x @n
источник

IO

I O in Haskell
А вот так работает

bar :: forall n . KnownNat n => String
bar = case SomeNat (Proxy @n) of
 SomeNat (Proxy :: Proxy m) -> x @m
источник

DM

Dmitriy Mozhevitin in Haskell
а на оба стула — компайл-тайм проверку для константных значений и рантайм-проверку для неизвестных в компайл-тайме значений не усесться?
источник

DB

Danil Berestov in Haskell
Разве есть какая-то рантайм проверка?
источник

MK

Maxim Koltsov in Haskell
(KnownSymbol anyName, (anyName == "") ~ 'False) попробуй
источник

MK

Maxim Koltsov in Haskell
но скорее всего не выйдет
источник