[英]Invisible type signature in Haskell
I want to use ambiguous type a
in function as follows, but it fails. 我想在函数中使用模糊类型a
,如下所示,但它失败了。
foo :: (Read a, Show a) => IO ()
foo = print =<< (readLn :: IO a)
The purpose is to get different outputs regarding to the given type signature when actually called. 目的是在实际调用时获得与给定类型签名不同的输出。
>>> foo :: Double => IO ()
34 -- user input
34.0 -- output
>>> foo :: Int => IO ()
34 -- user input
34 -- output
How can I manage this? 我该怎么办呢?
The simplest way is to manifest your type variable. 最简单的方法是显示您的类型变量。 For example, using a newish GHC: 例如,使用新的GHC:
{-# LANGUAGE ScopedTypeVariables #-}
foo :: forall proxy a. (Read a, Show a) => proxy a -> IO ()
foo _ = print (read "34" :: a)
Then, in ghci: 然后,在ghci:
Data.Proxy *Main> foo (Proxy :: Proxy Double)
34.0
Data.Proxy *Main> foo (Proxy :: Proxy Int)
34
Or, a more exotic usage, relying on more implicit Haskell behavior: 或者,更奇特的用法,依赖于更隐式的Haskell行为:
*Main> foo [0.0]
34.0
*Main> foo [0]
34
Neither foo :: Double => IO ()
nor foo :: Int => IO ()
are valid signatures, since Double
and Int
aren't constraints. foo :: Double => IO ()
和foo :: Int => IO ()
都不是有效签名,因为Double
和Int
不是约束。
However, you could easily make the function polymorphic in its return type and write it the following way: 但是,您可以轻松地在其返回类型中使函数具有多态性,并按以下方式编写它:
foo :: (Read a, Show a) => IO a
foo = let x = read "34" in print x >> return x
That way, you can use foo :: IO Double
or foo :: IO Integer
: 这样,你可以使用foo :: IO Double
或foo :: IO Integer
:
ghci> foo :: IO Double
34.0 -- print
34.0 -- result, you would discard it
ghci> foo :: IO Integer
34
34
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.