【问题标题】:Haskell apply function arrow to only result type?Haskell 仅将函数箭头应用于结果类型?
【发布时间】:2014-05-22 16:15:16
【问题描述】:

是否可以在 Haskell 中将函数箭头类型构造函数 (->) 仅应用于其右侧类型(例如:(-> a))以获得类型 * -> * 的类型构造函数?

【问题讨论】:

  • 是的,我宁愿避免这样做,因为它会使事情变得更复杂一些。我几乎可以肯定我已经完成了。
  • 原来是的,我确实需要一个新类型。如果您将其发布为答案,我会接受它,以便您获得荣誉。
  • @htbta 它有正确的类型,但它不满足另一个约束:他想将(->) 应用于它的第二个参数,而不是第一个。
  • @Daniel Wagner GHC 具有 (->) :: * -> * -> *(,) :: * -> * -> * 以及部分类型级应用程序 (->) a :: * -> *(,) a :: * -> *,但没有类型级部分(如 (a ->)、@ 987654331@、(a,)(,a))或类型级 lambda(例如 ?b a -> (->) a b)。所以使用newtype 是唯一的选择。

标签: haskell types type-kinds


【解决方案1】:

不,目前不可能。 Haskell 的类型系统有一些限制,使其在大多数情况下都很有用和方便,这就是这些限制之一。您最好的选择是使用新类型。

newtype FuncFlip r a = FuncFlip { unFuncFlip :: a -> r }

新类型只是帮助编译器知道如何正确地进行类型检查和执行类型定向调度(类型类)的标记。大概您想翻转类型参数以提供一些类型类实例。这只是意味着,每当您想使用该类型类的函数时,您必须使用FuncFlip 装饰任何特定的输入,并使用unFuncFlip 取消装饰任何特定的输出。这比预期的要冗长一些,但实际上并没有那么糟糕,因为它会强制您明确识别要使用的类型类的哪个实例。

您可以为此创建一个Newtype 的实例,这可能会或可能不会对您方便。

instance Newtype (FuncFlip r a) (a -> r) where
  pack = FuncFlip
  unpack = unFuncFlip

延伸阅读:Are there "type-level combinatos?"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 2016-11-09
    • 2015-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多