gpt4 book ai didi

elm - 设计多态API

转载 作者:行者123 更新时间:2023-12-04 19:59:58 26 4
gpt4 key购买 nike

我有一个 Scale 的概念,它在输入域和输出范围之间进行转换。然而,有几种类型的秤;每个都支持可能操作的子集并存储略有不同的范围。

例如:

一个 Continuous具有域 Scale (Float, Float) (Float, Float) 的比例 ((Float, Float))和范围 (Float, Float)支持:

  • convert : Continuous -> Float -> Float将值从域转换为范围。
  • invert : Continuous -> Float -> Float将值从范围转换回域。
  • domain : Continuous -> (Float, Float)返回域。
  • ticks : Continuous -> List Float返回适合在轴上绘制的值。

  • 一个 Sequential scale 的域为 (Float, Float)以及来自 Float -> a 的函数,存储范围通常没有多大意义。
  • convert : Sequential a -> Float -> a将值从域转换为范围。
  • domain : Sequential a -> (Float, Float)返回域。

  • 一个 Quantile scale 将采样的输入域 ( List Float) 映射到离散范围 ( List a)。该域被认为是连续的;但是,域被指定为一组离散的样本值。
  • convert : Quantile a -> Float -> a将值从域转换为范围。
  • invertExtent : Quantile a -> a -> (Float, Float)从与范围相对应的域中返回一个范围。

  • 如果上面的示例没有多大意义,请不要担心。要点是有几种类型的对象共享一些逻辑操作,但不是全部。某些操作仅由某些类型而不是所有类型共享。某些操作仅对某些类型具有“特殊”行为,但对于其他操作可能默认为合理的回退(即 identity ),在其他情况下则没有合理的实现。能够在所有可能的范围内或在支持特定操作的所有范围内指定通用算法也非常有用。

    我将如何在 Elm 中设计这样的 API?

    到目前为止我有一些不好的想法:
  • 检查是否支持实现,否则抛出运行时错误。呸。
  • 将这些包装在模块的层次结构中,调用者需要知道他们需要执行什么级别的包装/展开来调用适当的方法。这对于调用者来说似乎非常难看,而且 API 很难使用。也无法处理所有情况。
  • 有一个类似于 Scale supportsOp1 supportsOp2 supportsOp3 的类型其中每个类型变量的类型都可以是 SupportsOpDoesnt .然后我可以有一个功能,例如op1 : Scale SupportsOp a b -> c .这可以解决问题,但类型注释非常难看。此外,我不完全确定如何处理实际存储实际类型的范围和域的类型。
  • 使用临时类型类。因此,对于每次调用,您都必须传递具有适当实现的记录。这几乎奏效了。对于 API 的使用者来说,这有点痛苦——它在某种程度上违背了官方建议,因为它鼓励您存储函数并传递它们。
  • 最佳答案

    是否可以定义单一类型 Scale a以及 scale 的每个子类作为不同的构造函数?

    type Scale a
    = Continuous (Float, Float) (Float, Float)
    | Sequential (Float, Float) (Float -> a)
    | Quantile (List Float) (Float -> a)
    SequentialQuantile两者都需要类型参数,而 Continuous没有,所以这有点难看。 Continuous 的类型参数有意义吗?让其中一个值让它更干净一点?

    如果您能够使用单一类型,那么处理该类型将变成一系列 case陈述。

    convert : Scale a -> Float -> a
    convert scale val =
    case scale of
    Continuous domain range -> ...
    Sequential domain mapper -> ...
    Quantile domain mapper -> ...

    而不是抛出运行时错误,您可以更改函数签名以返回 Maybe a并返回 Nothing在不受支持的操作上?虽然您无法在函数调用之前确定支持,但您至少必须显式处理 Nothing值被返回,这最终成为事后检查支持的方式。

    invertExtent : Scale a -> a -> Maybe (Float, Float)
    invertExtent scale val =
    case scale of
    Continuous _ _ -> Nothing
    Sequential _ _ -> Nothing
    Quantile domain mapper -> Just (...)

    关于elm - 设计多态API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39020620/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com