私はそれが動作するようになったが、私は疑問言語オプションの束をオンにする必要がありました-hoc多型)は、複数の型の下で同じ名前をバインドするのではなく、型クラスを使用することによって実現されます。
{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
class F a where f :: String -> a
instance F String where f = id
instance F Int where f = read
instance F Char where f = read
instance F Float where f = read
-- etc.
さて、f
はF
のインスタンスが宣言された任意の型を操作することができます。
残念ながら、あなたは次のように逃げることができません。
instance Read a => F a where f = read
を多分unintuitively、これははRead
のインスタンスを持っているタイプのためF
のインスタンスを宣言していません。 GHCはインスタンス宣言の先頭(=>
の右側の部分)のみを使用してインスタンスを解決するため、実際にはすべてのタイプa
がF
のインスタンスであると宣言しますが、それ以外の場合はf
を呼び出すタイプエラーになりますRead
のインスタンス
UndecidableInstances
拡張機能を有効にするとコンパイルされますが、これは他の問題につながります。あなたが本当に冒険したくないウサギの穴です。
代わりに、f
を操作する予定の個々のタイプごとにF
のインスタンスを宣言する必要があります。これは、このような単純なクラスのために非常に負担はありませんが、GHCの最新バージョンを使用している場合、あなたはそれが少し楽にするために、次を使用することができます任意のタイプのため、
{-# LANGUAGE DefaultSignatures #-}
class F a where f :: String -> a
default f :: Read a => String -> a
f = read
今Read
のインスタンスは、明示的f
の実装を提供することなく、F
のそのインスタンスを宣言することがあります。Read
のインスタンスなしには、いかなる種類のについては
instance F Int
instance F Char
instance F Float
-- etc.
を、あなたはまだのための明示的な実装を作成する必要があります。
出典
2012-03-27 00:51:55
pat
パフォーマンスについて懸念しているのであれば、これらの種類のものはコンパイラによって最適化されるはずです。 – leftaroundabout
私はパフォーマンスについて心配していません。文字列の前後に引用符は必要ない 'read'のバージョンが必要ですが、それ以外の場合は通常の' read'として動作します。 –
質問はhttp://stackoverflow.com/questions/9870962/haskell-making-a-superclass-of-num/とまったく同じ問題に対処しています。いくつかの答えが役に立つかもしれません。 –