首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类Printf函数

类Printf函数
EN

Stack Overflow用户
提问于 2015-09-04 13:47:28
回答 1查看 165关注 0票数 2

我试图用任意数量的参数来编写一个函数。这些参数可以是Int或String。我对ints有个问题。由于某些原因(我不明白),值1成为歧义的来源。如何处理这个错误,它的来源是什么?

代码语言:javascript
复制
{-# LANGUAGE FlexibleInstances #-}
import Data.Typeable

data PackArgTypes = PackInt Int | PackString String
                              deriving Show

class PackArg t where
  toPackArg :: t -> PackArgTypes

instance PackArg Int where
  toPackArg = PackInt . fromIntegral
instance PackArg Integer where
  toPackArg = PackInt . fromIntegral

instance PackArg String where
  toPackArg = PackString

class PackType t where
  pack' :: String -> [PackArgTypes] -> t

instance PackType (IO a) where
  pack' fmt acc = do
    print fmt
    mapM_ print acc
    return undefined

instance (PackArg a, PackType r) => PackType (a -> r) where
    pack' fmt acc = \x -> pack' fmt $ acc ++ [toPackArg x]

pack :: (PackType t) => String -> t
pack fmt = pack' fmt []

main :: IO ()
main = do
  pack "asd" "qwe" "asd"(1 :: Int) -- Ok
  pack "asd" "qwe" "asd" 1         -- Sad

在这种情况下,我得到了错误

代码语言:javascript
复制
test1.hs:33:3-6: No instance for (PackArg a0) arising from a use of ‘pack’ …
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance PackArg String
    -- Defined at /home/knesterov/test1.hs:13:10
  instance PackArg Int -- Defined at /home/knesterov/test1.hs:10:10
In a stmt of a 'do' block: pack "asd" "qwe" "asd" 1
In the expression: do { pack "asd" "qwe" "asd" 1 }
In an equation for ‘main’: main = do { pack "asd" "qwe" "asd" 1 }
test1.hs:33:26: No instance for (Num a0) arising from the literal ‘1’ …
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance Num Double -- Defined in ‘GHC.Float’
  instance Num Float -- Defined in ‘GHC.Float’
  instance Integral a => Num (GHC.Real.Ratio a)
    -- Defined in ‘GHC.Real’
  ...plus 7 others
In the fourth argument of ‘pack’, namely ‘1’
In a stmt of a 'do' block: pack "asd" "qwe" "asd" 1
In the expression: do { pack "asd" "qwe" "asd" 1 }
Compilation failed.

编辑

感谢user5402,他指出了ghci和ghc之间的区别。Ghci通过ExtendedDefaultRules启用默认设置扩展

因此,再加上三行,我的示例工作时没有错误。

代码语言:javascript
复制
{-# LANGUAGE ExtendedDefaultRules #-}
instance PackArg Integer where
  toPackArg = PackInt . fromIntegral
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-04 14:01:11

问题在于:

代码语言:javascript
复制
The type variable ‘a0’ is ambiguous
Note: there are several potential instances:
  instance Num Double -- Defined in ‘GHC.Float’
  instance Num Float -- Defined in ‘GHC.Float’
  ...

回想一下,文字1可以被解释为任何Num类型的值,所以GHC不知道选择哪一个-例如IntDoubleRational等等。

标准的Text.Printf模块也有同样的问题:

代码语言:javascript
复制
import Text.Printf

main = putStrLn $ printf "%d" 3

给了他同样的错误。

请注意,如果在ghci中输入此代码将不会得到错误,因为存在默认规则,使得表达式1是单形的,而不是多态的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32399733

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档