这是我问过的早期question的后续内容。现在,我正在尝试修改toText
方法,以便它还使用重载Maybe a
函数处理toText
。下面是一个编译和工作正常的代码 - 现在,我想为toText
使用Maybe a
定义本身为其他类型重载toText
:
{-# LANGUAGE TypeFamilies, DataKinds, MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables, FlexibleContexts #-}
import Data.List
import Data.Text (unpack, pack, Text, empty)
import Data.Proxy
import Data.Maybe (maybe)
data ToTextMethod = TTMText | TTMShow | TTMMaybe
type family ToTextHow a where
ToTextHow Text = TTMText
ToTextHow (Maybe b) = TTMMaybe
ToTextHow a = TTMShow
class ToTextC a b where
toTextC :: a -> b -> Text
instance Show a => ToTextC a (Proxy TTMShow) where
toTextC a _ = pack (show a)
instance Show a => ToTextC (Maybe a) (Proxy TTMMaybe) where
-- Will like to replace this with
-- toTextC a _ = maybe empty toText a
toTextC a _ = maybe empty (pack . show) a
instance ToTextC Text (Proxy TTMText) where
toTextC t _ = t
toText :: forall a. (Show a, ToTextC a (Proxy (ToTextHow a))) => a -> Text
toText x = toTextC x (Proxy :: Proxy (ToTextHow a))
如果我按以下评论中的说明更新toTextC
类型的TTMMaybe
定义:
instance Show a => ToTextC (Maybe a) (Proxy TTMMaybe) where
toTextC a _ = maybe empty toText a
我得到了这个错误 - 会对如何解决这个重载的指点表示赞赏:
Could not deduce (ToTextC a (Proxy (ToTextHow a)))
arising from a use of ‘toText’
from the context (Show a)
bound by the instance declaration at Test.hs:21:10-53
In the second argument of ‘maybe’, namely ‘toText’
In the expression: maybe empty toText a
In an equation for ‘toTextC’: toTextC a _ = maybe empty toText a
更新1:
根据评论中的建议,我使用额外的约束来修复它。但是,需要启用UndecidableInstances
扩展程序!有没有更好的方法可以在不使用UndecidableInstances
的情况下执行此操作?也许某种类型的运算符或函数来表达类型级计算?
instance (Show a,ToTextC a (Proxy (ToTextHow a))) => ToTextC (Maybe a) (Proxy TTMMaybe) where
toTextC a _ = maybe empty toText a