0

我想编写一个函数,它对 double 和任何其他类型的支持乘法和加法的数字进行操作,结果产生 double 。下面的当然不能编译,因为 (*) 的类型是 t -> t -> t,所以不允许混合不同的类型:

f :: (Num a) => Double -> a -> a -> Double
f x a b = a*x + b

我想要的是能够写出这样的东西:

f :: ...
f x a b = ... -- equivalent to a*x + b

f 1.0 (2 :: Int)    (3 :: Int)    -- returns 5.0
f 1.0 (2 :: Word32) (3 :: Word32) -- returns 5.0
f 1.0 (2 :: Float)  (3 :: Float)  -- returns 5.0

我应该怎么做才能让它工作?或者也许我从根本上错了,不应该这样做?这很奇怪,但我在互联网上没有找到任何关于此的内容。

4

2 回答 2

3

RWH.chapter6中有一段很好的关于在某些数字类型之间转换数字的段落(表 6.4)

f :: (Real a) => Double -> a -> a -> Double
f x a b = x * (cast a) + (cast b)
  where cast = fromRational . toRational

似乎可行。

> f 1.0 (2 :: Int)    (3 :: Int)
5.0
it :: Double
> f 1.0 (2 :: Word32) (3 :: Word32)
5.0
it :: Double
> f 1.0 (2 :: Float)  (3 :: Float)
5.0
it :: Double
于 2012-04-22T11:27:17.950 回答
1

使用类型类的机制进行“重载”:

import Data.Word
import GHC.Float

class F a where f :: Double -> a -> a -> Double
instance F Int where f x a b = fromIntegral a * x + fromIntegral b
instance F Word32 where f x a b = fromIntegral a * x + fromIntegral b
instance F Float where f x a b = float2Double a * x + float2Double b

tests =
  [ f 1.0 (2 :: Int) (3 :: Int)
  , f 1.0 (2 :: Word32) (3 :: Word32)
  , f 1.0 (2 :: Float) (3 :: Float)
  ]
-- > tests
-- [5.0,5.0,5.0]
-- > :t it
-- it :: [Double]

另见http://www.haskell.org/haskellwiki/Converting_numbers

于 2012-04-22T11:51:38.397 回答