首页 > 解决方案 > 类定义haskell中的模棱两可的类型

问题描述

我正在学习 Haskell,在我的宠物项目中我定义了几种新类型。简化时,它们是这样的

newtype A = A [Double]

我不希望类型 A 仅由任何双打列表创建,而是由满足某些条件的列表创建。此外,我希望能够获取列表,通过某些函数 Double->Double 对其进行转换,然后再次从中创建类型 A。由于我想为几种不同的类型执行此操作,因此我正在考虑定义类

class Functor f => Transform a f b err where
  create :: f b -> Either err a
  get :: a -> f b
  transform :: (b -> b) -> a -> Either err a
  transform f a= create  (f <$> (get a)

并创建实例

instance Transformator A [] Double String where
   create [] = Left "err"
   create xs = Right $ A xs
   get (A xs) = xs
   

但这似乎在 Haskell 中是不允许的。问题似乎是get的返回类型与create的输入类型不同,transform函数中的模糊类型f似乎无法在get和create之间配对。

最后我放弃并用两个类型类解决了这个问题:

class Transform a b err where
  transform :: (b -> b) -> a -> Either err a

class Create a b err where
  create :: b -> Either err a

newtype A = A [Double]

instance Create A [Double] String where
  create [] = Left "err"
  create xs = Right $ A xs

instance Transformator A Double String where
  transform f (A ps)= create  $ f <$> ps 

这工作得很好,但转换函数始终具有相同的实现 - 从类型内部获取数据,fmap 函数覆盖它们并在结果上应用 create。有什么方法可以使默认实现工作吗?此外,如果您有一些完全不同的建议如何解决这个问题,我会很高兴任何提示。

标签: haskelltypeclass

解决方案


推荐阅读