Виды ограничений Haskell - ограничение по умолчанию для реализации по умолчанию
Заголовок: я хотел бы предоставить реализацию по умолчанию для метода класса, параметризованного над ограничением, который использует экземпляр по умолчанию для этого ограничения.
Учтите следующее:
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
import GHC.Exts (Constraint)
class Foo a where
type Ctx a :: Constraint
type Ctx a = Show a
foo :: (Ctx a) => a -> String
foo = show
main :: IO ()
main = putStrLn "Compiles!"
Это не скомпилируется с ошибкой:
Could not deduce (Show a) arising from a use of ‘show’ from the context (Foo a)
С моей точки зрения, он должен использовать ограничение по умолчанию Show
, который позволил бы это скомпилировать. Есть ли причина, по которой это не работает, или кто-нибудь может предложить хороший способ добиться этого?
1 ответ
Вы можете добиться этого, используя DefaultSignatures
:
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE DefaultSignatures #-}
import GHC.Exts (Constraint)
class Foo a where
type Ctx a :: Constraint
type Ctx a = Show a
foo :: (Ctx a) => a -> String
default foo :: Show a => a -> String
foo = show
main :: IO ()
main = putStrLn "Compiles!"
С моей точки зрения, он должен использовать ограничение по умолчанию Show, что позволило бы скомпилировать.
Причина, по которой ваш подход не работает, состоит в том, что пользователь вашего класса должен иметь возможность переопределить любое количество значений по умолчанию. Ваш код сломался бы, если бы кто-то попытался переопределить Ctx
но нет foo
,