绑定到Haskell数据结构内部的monad

时间:2018-10-18 19:41:11

标签: haskell

有没有一种方法可以定义只影响数据结构一部分的绑定?

例如,假设我们有一个模拟计算数据类型,该数据类型具有名称和结果。

type Name          = String
data Error         = TimeOut | NotEnoughMemory | DivByZero
type Result a      = Either Error a
data Computation a = Computation Name (Result a)

由于计算可能会失败,但是我们可能仍对它的名称感兴趣,因此它不能成为Result的一部分,而必须是Computation的一部分。另一方面,直接绑定和验证计算结果也很方便,就像对常规Either类型所做的那样。有办法吗?

2 个答案:

答案 0 :(得分:2)

不,您可能无法定义任何有用的componentDidMount,因为您无法从instance Monad Computation类(这是pure :: a -> Computation a的超类)中定义Applicative。给定Monad类型的值,如何实例化Name

尽管它是a(并且您可以自动获得它)。有了更多的上下文,可能会有另一种抽象会更有用。

答案 1 :(得分:2)

TW monad transformers

我想你可能想要

 Using TensorFlow backend.
 2018-10-18 17:25:04.773578: I tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
 Results: -32.57 (23.16) MSE

 real   1m48.847s
 user   2m15.792s
 sys    0m13.440s

请注意,type Computation = ExceptT Error (Writer Name) -- in familiar types: -- Computation a ⋍ (Either Error a, Name) 现在必须是Name。这是有道理的,因为

Monoid

(用于添加两个子计算的结果)也需要有一个名称。 liftA2 (+) comp1 comp2 组件的作用是将两个子计算的名称串联在一起(与monoid的Writer —不一定只是字符串串联在一起)。也许您会使用例如:

<>

您可能还需要一种定义某些计算名称的方法:

newtype Name = Name [String]
    deriving (Semigroup, Monoid)

例如:

name :: String -> Computation a -> Computation a
name n = mapExceptT (censor (const (Name [n])))