がんばるならこんな感じですかね?
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
module Main where
main :: IO ()
main = do
print $ base (Search $ Noun "a" "b") ""
data Noun
= Noun
{ nounSurf :: String
, nounBase :: String
}
deriving (Eq, Ord, Read, Show)
instance HasBase Noun String where
base _ _ = 0
instance HasBaseFlipped String Noun
newtype Search
= Search
{ searchNoun :: Noun
}
deriving stock (Eq, Ord, Read, Show)
deriving newtype (HasBaseFlipped String)
class HasBase a b where
base :: a -> b -> Int
class HasBaseFlipped a b where
base' :: b -> a -> Int
default base' :: HasBase b a => b -> a -> Int
base' = base
instance {-# OVERLAPPABLE #-} HasBaseFlipped b a => HasBase a b where
base = base'