これは、私が尋ねた以前の質問のフォローアップです。今、オーバーロードされた関数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