私は何でも含むことができる普遍的なデータ型を定義しました (まあ、現在の実装では完全に何もではありません)!
ここにあります(完全なコード):
{-#LANGUAGE NoMonomorphismRestriction#-}
{-#LANGUAGE GADTs#-}
{-#LANGUAGE StandaloneDeriving#-}
data AnyT where
Any :: (Show a, Read a) => a -> AnyT
readAnyT :: (Read a, Show a) => (String -> a) -> String -> AnyT
readAnyT readFun str = Any $ readFun str
showAnyT :: AnyT -> String
showAnyT (Any thing) = show thing
deriving instance Show AnyT --Just for convinience!
a = [Any "Hahaha", Any 123]
そして、コンソールで遊ぶことができます:
*Main> a
[Any "Hahaha",Any 123]
it :: [AnyT]
*Main> readAnyT (read::String->Float) "134"
Any 134.0
it :: AnyT
*Main> showAnyT $ Any 125
"125"
it :: String
うーん、持ってるけど何とか加工しないと。たとえば、変換関数を定義しましょう (関数定義、前のコードに追加)。
toAnyT :: (Show a, Read a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny :: AnyT -> a
fromAny (Any thing) = thing
そして、問題があります!前のコードのfromAny定義が正しくありません! そして、私はそれを正しくする方法がわかりません。GHCiでエラーが発生します:
2.hs:18:23:
Could not deduce (a ~ a1)
from the context (Show a1, Read a1)
bound by a pattern with constructor
Any :: forall a. (Show a, Read a) => a -> AnyT,
in an equation for `fromAny'
at 2.hs:18:10-18
`a' is a rigid type variable bound by
the type signature for fromAny :: AnyT -> a at 2.hs:17:12
`a1' is a rigid type variable bound by
a pattern with constructor
Any :: forall a. (Show a, Read a) => a -> AnyT,
in an equation for `fromAny'
at 2.hs:18:10
In the expression: thing
In an equation for `fromAny': fromAny (Any thing) = thing
Failed, modules loaded: none.
エラーが発生する他の方法も試しました。
私はこれに対してかなり悪い解決策を持っています: showAnyTとreadを介して必要な関数を定義します(以前の関数定義を置き換えます):
toAnyT :: (Show a, Read a) => a -> AnyT -- Rather useless
toAnyT a = Any a
fromAny :: Read a => AnyT -> a
fromAny thing = read (showAnyT thing)
はい、仕事です。私はそれで遊ぶことができます:
*Main> fromAny $ Any 1352 ::Float
1352.0
it :: Float
*Main> fromAny $ Any 1352 ::Int
1352
it :: Int
*Main> fromAny $ Any "Haha" ::String
"Haha"
it :: String
しかし、文字列を使用して変換するため、悪いと思います。
きちんとした良い解決策を見つけるのを手伝ってくれませんか?