Haskell 重载函数名的更简单语法

Haskell 重载函数名的更简单语法,haskell,typeclass,overloading,Haskell,Typeclass,Overloading,在具有类型族扩展的Haskell中,这是完全合法的(): 基本上我定义了两个函数get 带有类型签名的一个: get :: A -> Int 第二点: get :: B -> Double 然而,上面的代码中有很多错误。我希望能够做到的是: get :: A -> Int get (A x) = x get :: B -> Double get (B x) = x 我明白使用这种语法是行不通的,但是有没有什么方法可以在没有十几行定义类型实例和类实例的情况下实现我想

在具有类型族扩展的Haskell中,这是完全合法的():

基本上我定义了两个函数
get

带有类型签名的一个:

get :: A -> Int
第二点:

get :: B -> Double
然而,上面的代码中有很多错误。我希望能够做到的是:

get :: A -> Int
get (A x) = x

get :: B -> Double
get (B x) = x

我明白使用这种语法是行不通的,但是有没有什么方法可以在没有十几行定义类型实例和类实例的情况下实现我想要的呢?考虑到第一段代码运行良好,我认为Haskell编译器没有理由不能将这段较短的代码转换为上述代码。

这应该可以完成以下工作:

class Get a b | a -> b where
  get :: a -> b

instance Get A Int where
  ...

好吧,所以它只去掉了类型族。我认为您无法摆脱类型类,因为它们是实现重载的方法。此外,如果没有类,您将无法以类型表示类约束,例如,您无法编写以下内容:

getPaired :: (Get a b, Get c d) => (a, c) -> (b, d)

我不知道这是否适用于您的用例-您的示例相当做作。但您可以在此处使用GADT而不是类型类:

data T a where 
  A :: Int -> T Int 
  B :: Double -> T Double 

get :: T a -> a
get (A x) = x
get (B x) = x

一般来说,没有办法让编译器猜测您想要编写什么代码并为您编写。我怀疑,这样的编译器会淘汰大多数程序员,所以我们都应该庆幸它不存在。我确实同意你写了很多东西,但做的很少,但这可能是你的代码有问题的迹象,而不是编译器的缺陷

这里是另一种选择:

{-# LANGUAGE TypeFamilies #-}

data A = A Int
data B = B Double

class Get a where
    type F a
    get :: a -> F a

instance Get A where
    type F A = Int
    get (A x) = x

instance Get B where
    type F B = Double
    get (B x) = x

main = print (get (A 3), get (B 2.0))
在我看来,它比函数依赖性更好。
所有的东西都在

中描述,我将以此作为答案。每个定义两行,设置两行,很好地完成了工作。
{-# LANGUAGE TypeFamilies #-}

data A = A Int
data B = B Double

class Get a where
    type F a
    get :: a -> F a

instance Get A where
    type F A = Int
    get (A x) = x

instance Get B where
    type F B = Double
    get (B x) = x

main = print (get (A 3), get (B 2.0))