简体   繁体   English

Haskell中的隐形类型签名

[英]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 ()都不是有效签名,因为DoubleInt不是约束。

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 Doublefoo :: 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM