【问题标题】:Struggling with interface like approach in Haskell在 Haskell 中使用类似接口的方法苦苦挣扎
【发布时间】:2014-10-08 10:53:16
【问题描述】:

我在理解如何处理 Haskell 中的方法等接口时遇到问题。如果用 OOP 术语考虑它,那么我希望不同的对象实现相同的接口(只是几个方法)并跟踪一些内部状态。

我从一些类型类开始

class FileTransformer where
    doThis :: a -> b -> c
    doThat :: d -> e -> f

如果我会创建不同的数据类型,比如

data FirstThingy = FirstThingy { internalState :: STRef s Int } -- simplified
data SecondThingy = SecondThingy { differentState :: STRef s Word8 } -- simplified

instance FileTransformer FirstThingy where
    doThis = ... -- does some stuff with internal state also
    doThat = ... -- does some stuff with internal state also

-- implementation of doThis and doThat is different from the above one
instance FileTransformer SecondThingy where
    doThis = ... -- does some stuff with internal state also
    doThat = ... -- does some stuff with internal state also

然后我认为这样做就足够了:

firstThingy = FirstThingy someInitialState
secondThingy = SecondThingy someOtherInitialState

loadFileTransformer :: FileTransformer ft => FileHeader -> ft
loadFileTransformer header = if simple header then firstThingy else secondThingy

不过,你可能已经猜到这行不通了……

那么,问题是 Haskell 中的什么方法可以让我根据某些特定需求选择不同的文件转换器?每个转换器必须有 2 个方法(但有不同的实现),并且还可以有一些内部状态(与彼此相比时非常不同)。

【问题讨论】:

    标签: haskell interface


    【解决方案1】:

    您可能需要考虑使用 ADT 来表示您的 Thingys,而不是两个单独的类型:

    data Thingy = FirstThingy (STRef s Int) | SecondThingy (STRef s Word8)
    

    然后你可以在Thingy上进行模式匹配:

    doThis :: Thingy -> a -> b -> c
    doThis (FirstThingy st) = ...
    doThis (SecondThingy st) = ...
    

    doThat 类似。那么您的最后一个代码块将如下所示:

    firstThingy = FirstThingy someInitialState
    secondThingy = SecondThingy someOtherInitialState
    
    loadFileTransformer :: FileHeader -> Thingy
    loadFileTransformer header
        | simple header = firstThingy
        | otherwise = secondThingy
    

    【讨论】:

    • 是的!谢谢!我知道这会很容易。
    【解决方案2】:

    与其尝试创建一个具有表示不同文件转换的内部状态的对象,您可能只想调用一个带有合适参数的函数

    如果不了解如何使用您的转换器,就很难确切地说出如何最好地构建它。但是,如果您有一个 doTheStuff 函数想要将“转换器对象”作为输入,为什么不让它只将两个“方法”作为参数以及初始状态值?

    doTheStuff :: state -> (state -> a -> b -> c) -> (state -> d -> e -> f) -> ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多