Syntax Haskell-重新定义(隐藏)算术运算符

Syntax Haskell-重新定义(隐藏)算术运算符,syntax,haskell,functional-programming,notation,Syntax,Haskell,Functional Programming,Notation,我想在Haskell中重新定义几个算术运算符,以使它们更具可扩展性和通用性 例如 这似乎与 import Prelude hiding ((*)) 隐藏标准的*运算符。当然,所有常用的乘法也必须起作用,所以我必须定义如下 instance (Num t) => Mul t t t where (*) = ?? import Prelude qualified ((*)) 如何在此处访问原始的*运算符(Prelude.*)不起作用),以及如何定义实例类型以使1*1不与单态限制冲

我想在Haskell中重新定义几个算术运算符,以使它们更具可扩展性和通用性

例如

这似乎与

import Prelude hiding ((*))
隐藏标准的
*
运算符。当然,所有常用的乘法也必须起作用,所以我必须定义如下

instance (Num t) => Mul t t t where
    (*) = ??
import Prelude qualified ((*))
如何在此处访问原始的
*
运算符(
Prelude.*)
不起作用),以及如何定义实例类型以使
1*1
不与单态限制冲突


编辑-

import qualified
这是一个很好的提示,谢谢

但不幸的是,这迫使我明确地将所有标准方法纳入范围。我只想有可能重新定义某些绑定,而保持其余绑定不变

那么这两者是否都有呢?差不多

instance (Num t) => Mul t t t where
    (*) = ??
import Prelude qualified ((*))

有一些人尝试过这样做

首先,

如何访问原始*运算符(前奏曲(*)不工作)

您需要:

import qualified Prelude 
现在您可以使用例如(Prelude.*)。这比“LANGUAGE NoImplicitPrelude”的攻击性要小,后者还将导致>>=等的本地使用恢复到您的定义中

以下是其他人的备选前奏曲示例:

  • ——简单的序曲(?)
  • --另一种数字层次结构

    • 我可以回答第一个问题。隐藏(*)运算符实际上会隐藏它,因此无法获取它。但是,您可以导入Prelude qualified:

      import qualified Prelude as P
      
      foo = 3 P.* 14 -- == 42
      

      我想这正是你想要的。

      回答编辑后的问题:

      你能行

      import Prelude hiding ((*))
      import qualified Prelude as P
      
      要以常规方式访问除
      (*)
      之外的所有前奏曲功能,并通过
      p
      前缀访问
      (*)

      x = 5 + 3   -- works
      y = 5 P.* 3 -- works
      z = 5 * 3   -- complains about * not being in scope
      
      实例

      instance (Num t) => Mul t t t where
          (*) = ??
      
      将在很大程度上挫败首先定义
      mult
      的目的,而不会滥用扩展来允许
      {-#语言重叠实例}

      不幸的是,如果痛苦的话,“正确的”答案是逐个实例地进行,然后

      import Prelude hiding ((*))
      import qualified Prelude 
      
      instance Mul Int Int Int where
          (*) = (Prelude.*)
      
      instance Mul Double Double Double where
          (*) = (Prelude.*)
      
      
      instance Mul Int Double Double where
          ...
      
      instance Mul (Complex Float) (Complex Double) (Complex Double)
          ...
      
      否则,实例头在编译器中得到解析的方式(不进行回溯)可能会使新实例在实际使用它们时导致编译失败

      也就是说,你至少可以减轻你没有想到的痛苦:

      newtype Other a = Other a
      
      instance Num a => Mul (Other a) (Other a) (Other a) where
          Other a * Other b = Other (a Prelude.* b)
      

      如果他们不想自己去定义Mul和所有其他类,这至少可以让他们使用您的newtype包装器。

      谢谢-这就是我想要的。