私はputStrLn $ showManyP "%d" 10
のようなファイルをロードした後GHCiの中で何かをしようとすると、それは動作しますが、これは動作しませんなぜ私は、ファイル main = putStrLn $ showManyP "%d" 10
作品ではなく、ファイル内
でそれを書くときには、このエラーを与えます
printf.hs:37:19:
Ambiguous type variable `a0' in the constraints:
(Format a0) arising from a use of `showManyP' at printf.hs:37:19-27
(Num a0) arising from the literal `10' at printf.hs:37:34-35
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely `showManyP "%d" 10'
In the expression: putStrLn $ showManyP "%d" 10
In an equation for `main': main = putStrLn $ showManyP "%d" 10
Failed, modules loaded: none.
実際のファイルはここから始まります:GHCで
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}
import Data.List (intercalate,isPrefixOf)
class Showable a where
showManyP :: String -> a
instance Showable String where
showManyP str = str
instance (Showable s,Format a) => Showable (a->s) where
showManyP str a = showManyP (format str a)
class Format a where
format :: String -> a -> String
instance Format String where
format str a = replace "%s" str a
instance Format Char where
format str a = replace "%c" str [a]
instance Num a=>Format a where
format str a = replace "%d" str (show a)
replace :: String -> String -> String -> String
replace f str value = intercalate value $ split str f
split :: String -> String -> [String]
split [] f = [[]]
split str [] = [str]
split [email protected](x:xs) f | isPrefixOf f str = [[],drop (length f) str]
| otherwise = let (y:ys) = split xs f
in [x:y] ++ ys
これは完全に正しいわけではありません。 'default(Integer、Double)'の宣言に相当する、コンパイルされたHaskellモジュールでデフォルトの_is_を有効にします。しかし、 'Format'は標準クラスではないので、この場合は適用されません。 (あなたの最初のリンクを参照してください)。しかし、GHCiでは、この制限が解除されている。 – hammar
上記の場合、Formatのデフォルト宣言を追加する方法を教えてください。 – Satvik