Haskell 函数签名的别名

Haskell 函数签名的别名,haskell,functional-programming,Haskell,Functional Programming,我正在Haskell中实现kNN算法。因此,我需要距离函数。 第一个很好用 import Data.Composition import Data.Vector taxicab :: Num a => Vector a -> Vector a -> a taxicab = Data.Vector.sum .: Data.Vector.zipWith (\ x y -> abs $ x - y) 如何为Num a=>Vector a->Vector a->a创建别名Di

我正在Haskell中实现kNN算法。因此,我需要距离函数。 第一个很好用

import Data.Composition
import Data.Vector

taxicab :: Num a => Vector a -> Vector a -> a
taxicab = Data.Vector.sum .: Data.Vector.zipWith (\ x y -> abs $ x - y)
如何为
Num a=>Vector a->Vector a->a
创建别名
Distance

我可以这样写:

taxicab :: Distance

您可能希望定义一个(或查看)。在没有参数的情况下,不可能直接包含类约束,但可以使用参数化类型同义词:

type Distance a = Vector a -> Vector a -> a

taxicab :: Num a => Distance a
这允许您使用不同的约束定义距离



一开始我错了:如果您添加一个参数,您可以这样做。

就像您为另一个类型创建类型别名一样:

type Distance a = Num a => Vector a -> Vector a -> a
事实上,函数是“类型构造函数”:如果您编写
a->b
,您就以更规范的形式编写了
(>)ab
,这意味着您基本上编写了:

type Distance a = Num a => (->) (Vector a) ((->) (Vector a) a)
但是请注意,我们需要在此处添加一个类型参数
a
,因此您的
taxicab
属于以下类型:

taxicab :: Distance a

taxicab::距离a
您想要的是距离a。我认为实现你想要的目标是不可能的(或不容易的)。您可以轻松地执行以下操作:
键入距离a=Vector a->Vector a->a
,然后使用
taxicab::Num a=>距离a
。如果您想使用肮脏的方式将
距离定义为宏,但无论如何都要避免这种情况……参数化类型
距离确实是个好主意。使用
RankNTypes
可以移动类型参数:
type Distance=forall a。Num a=>Vector a->Vector a->a
,给出所需的
taxicab::Distance