1

这是我之前提出的问题的后续。现在,我正在尝试修改该toText方法,以便它也可以处理Maybe a重载toText函数。下面是一个编译和工作正常的代码 - 现在,我想重载toTextMaybe atoText定义本身用于其他类型:

{-# 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 
4

0 回答 0