【问题标题】:type-class difficult inference类型类困难推理
【发布时间】:2015-12-21 10:38:29
【问题描述】:

我想让以下类型可推断:

class Lit a
instance Lit Int
instance Lit Float

class App a b
instance App Float b

f :: (Lit a, App a b) => a -> b -- a should be Float

我知道这个样本不能推断aFloat,因为至少类型类没有关闭。

我应该怎么做才能达到目的?

此外,我想做的是使用 TH 和 Haskell 类型检查器构建类型化 EDSL。例如,如果变量(Int 或 Float)“p”乘以 Float,我想将“p”推断为 Float。所以也欢迎解决这个问题。

【问题讨论】:

  • 如前所述,由于您提到的原因,这是无法解决的:类型类是开放的。你可以尝试使用函数依赖或类型族,如果它们可以实现你自己的目标。
  • 没错,我尝试了一些不同风格的代码,但任何尝试都没有成功......我想知道这可以使用封闭类型族解决,但我不知道怎么办。
  • 封闭类型族是不够的,你还需要单射类型族,它们很快就会出现(tm)。

标签: haskell types typeclass


【解决方案1】:

不清楚你想用这段代码解决什么问题,但正如@chi所说,你可以试试 FunDeps

  {-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}

  class Lit a
  instance Lit Int
  instance Lit Float

  class App a b | b -> a
  instance App Float b

  f :: (Lit a, App a b) => a -> Maybe b
  f x = Nothing

或类型族

{-# LANGUAGE TypeFamilies, FlexibleInstances #-}

class Lit a
instance Lit Int
instance Lit Float

class App res where
  type Arg res

instance App res where
  type Arg res = Float

f :: App b => Arg b -> Maybe b
f x = Nothing

在此示例中使用 FunDeps 更简洁,但根据我的经验,TypeFamilies + GADTs 解决方案对于类型级编程来说更直接且易于管理。

【讨论】:

  • 对不起,就我而言,就像instance App Double b... 我重新考虑了这个问题并得出结论我的问题无法解决,所以我决定明确写类型。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-01-04
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-02
  • 1970-01-01
相关资源
最近更新 更多