1

これは、私が尋ねた以前の質問のフォローアップです。今、オーバーロードされた関数toTextでも処理できるようにメソッドを変更しようとしています。以下は、コンパイルして正常に動作するコードです。ここで、他の型の定義自体を使用するためにオーバーロードしたいと思います。Maybe atoTexttoTextMaybe 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