有没有一种方法在ghc中重载并置运算符?

3
我希望能够在Haskell中设计一种嵌入式语言,并且如果可能的话,我希望能够为并列运算符赋予自定义含义,而这个运算符通常表示函数应用。 或者,几乎等效地,我想定义一个空格运算符,它具有可定义的正常运算符优先级。
类似于下面的样子:
( ) x y = x * y

这样就可以将乘法 3 * 4 写成 3 4

在 GHC 中是否有任何方法(使用任何必要的扩展)来实现这一点?


2
那很好,但你如何应用普通函数? - n. m.
它只应该针对某些类型进行重载,比如(在我的例子中)两个数字。 - chtenb
1
它无法与类型推断一起使用。 - n. m.
也许会。我可以想象一个“类型族参数(Argument)”,其中包含“类型实例参数(Argument (a -> b) a)”,其中术语“(x::a) (y::b)”将生成约束条件“Argument a ~ b”。当然,更多的代码需要进行类型注释,但这是可行的。 - Joachim Breitner
1个回答

5
实际上,是的!
{-# LANGUAGE FlexibleInstances #-}
module Temp where

instance Num a => Num (a -> a) where
  fromInteger n = (fromInteger n *)
  n + m = \x -> n x + m x
  -- ...

然后在 ghci 中:

λ :l Temp
...
λ 3 (4 :: Int) :: Int
12
λ let _4 = 4 :: Int
λ 3 _4 :: Int
12
λ (3 + 4) (2 :: Int) :: Int
14

在Haskell中,符号0, 1等是重载的 - 0 :: Num a => a - 它们可以表示任何具有Num实例的内容。因此,通过为函数Num a => a -> a定义一个Num实例,我们现在有了3 :: Num a => a -> a

1
3 (4 :: Int) :: Int3 * 4 相比几乎没有优势。 - n. m.
有没有可能让这个代码工作而不需要像在“3 _4 :: Int”中那样显式地将结果转换为“Int”? - chtenb
类型注释仅在 ghci 中需要。在源文件中,你可以这样写 twelve :: Int twelve = 3 4 - phadej
1
严格来说,这并不是重载对比。并列仍然是函数应用。尽管如此,它还是相当巧妙的! - Rein Henrichs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接