约束:两个类型变量可以与运算符一起使用

rlk*_*024 2 haskell functional-programming

我有以下功能编译并成功运行:

-- Linearly interpolates between two values. That is, it is a function which:
--   returns y1 when x = x1
--   returns y2 when x = x2
--   returns a value between y1 and y2 when x1 < x < x2
linearInterp x1 y1 x2 y2 x =
  (x - x1) * slope + y1
  where slope = (y2 - y1) / (x2 - x1)
Run Code Online (Sandbox Code Playgroud)

我想给它一个类型签名:

linearInterp :: a -> b -> a -> b -> a -> b
Run Code Online (Sandbox Code Playgroud)

但是,正如预期的那样,类型签名会导致编译错误.这是因为编译器不能确定这是可以做到的算术任意类型ab.例如,它不知道,你可以把b通过a,正如我在我的定义做slope.

有没有办法写出类型约束说" a / b有可能"," a + b有可能"等?我见过的Mul,DivSum类型类.但他们似乎并没有告诉编译器有关在两种不同类型上进行算术的事情.

如果你想知道,这对我来说很重要,因为我正在使用Dimensional包.确实可以对该包中的不同类型进行算术运算.所以,你可以,例如,拨打linearInterp其中type aLength Float和类型bVelocity Float.

GS *_*ica 5

如果我将代码包装在维度Prelude的导入中:

import Prelude ()
import Numeric.Units.Dimensional
import Numeric.Units.Dimensional.Prelude

linearInterp x1 y1 x2 y2 x =
  (x - x1) * slope + y1
  where slope = (y2 - y1) / (x2 - x1)
Run Code Online (Sandbox Code Playgroud)

我推断这种类型:

linearInterp
  :: (Fractional a, Mul d1 d' d, Div d d1 d') =>
     Dimensional DQuantity d1 a
     -> Dimensional DQuantity d a
     -> Dimensional DQuantity d1 a
     -> Dimensional DQuantity d a
     -> Quantity d1 a
     -> Quantity d a
Run Code Online (Sandbox Code Playgroud)

如果你想要那种普遍性,这似乎是一个非常合理的函数类型.

Mul,DivSum类型类实际上已告诉不同类型做算术编译器,因为它们是多参数类:他们每次取3点表示左参数的类型,正确的参数类型和结果类型的参数.