【问题标题】:Haskell - Redefining (hiding) arithmetic operatorsHaskell - 重新定义(隐藏)算术运算符
【发布时间】:2011-01-24 05:18:08
【问题描述】:

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

例如

class Mul a b c | a b -> c where
    (*) :: a -> b -> c

这似乎与

结合使用
import Prelude hiding ((*))

隐藏标准的* 运算符。但是当然所有常用的乘法也必须起作用,所以我必须定义类似

instance (Num t) => Mul t t t where
    (*) = ??

如何在此处访问原始 * 运算符(Prelude.(*) 不起作用)以及如何定义实例类型以使 1 * 1 不与 Monomorpism Restriction?


编辑 -

import qualified

是一个很好的提示,谢谢。

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

那么有没有两者兼而有之?类似的东西

import Prelude qualified ((*))

【问题讨论】:

    标签: syntax haskell functional-programming notation


    【解决方案1】:

    回答编辑后的问题:

    你可以的

    import Prelude hiding ((*))
    import qualified Prelude as P
    

    以常规方式访问除 (*) 之外的所有 Prelude 功能,并通过 P 前缀访问 (*)

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

    【讨论】:

    • 谢谢 - 这就是我想要的。
    【解决方案2】:

    实例

    instance (Num t) => Mul t t t where
        (*) = ??
    

    将在很大程度上破坏首先定义 Mul t t t 的目的,而不会滥用扩展来允许 {-# LANGUAGE OverlappingInstances #-}

    不幸的是,如果痛苦的答案是“正确”,那就是逐个实例地去做

    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 包装器。

    【讨论】:

      【解决方案3】:

      有一些尝试做这样的事情。

      首先,

      如何访问原始 * 运算符(Prelude.(*) 不起作用)

      您需要:

      import qualified Prelude 
      

      现在您可以使用例如(序幕。*)。这不如“LANGUAGE NoImplicitPrelude”那么激进,后者还会导致 >>= 等的本地使用被反弹到您的定义中。

      以下是其他人的替代前奏的示例:

      【讨论】:

        【解决方案4】:

        我可以回答第一个问题。隐藏 (*) 运算符真的隐藏了它,所以你无法得到它。但是,您可以导入 Prelude 限定:

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

        我认为这就是你想要的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-27
          • 1970-01-01
          • 2020-03-10
          相关资源
          最近更新 更多