我如何使用某些新类型分组

How do I work with certain groupings of newtypes

我正在尝试让以下内容正常工作,但我似乎做不好。我希望这样的事情能起作用:

newtype Skill = Skill { name :: String, other :: Int }
newtype Feature = Feature { name :: String, something :: Boolean }
newtype Special = Special { name :: String, different :: String }

type Namable = forall r. { name :: String | r }

changeName :: forall m. String -> m Namable -> m Namable
changeName newName (ctor namable) = 
    ctor $ namable { name = newName }

错误类似于:

Error 1 of 1
  Unable to parse module:
  unexpected "namable"
  expecting @, ::, operator or )

基本上我想为一组 newtype 添加功能。这并不总是整个集合,也不总是超过一个,但我想编写我定义的类型的实际功能 "ignorant"。如果将来我决定添加 newtype Statistic,我希望它成为 "just work"。

为了改进这个问题,我想知道是否有我正在寻找的签名类型的名称?

f :: forall m a. (a -> a) -> m a -> m a

似乎是一个不太通用的 Functor 定义。

看来我需要的是 Newtype 类型类:

newtype Skill = Skill { name :: String, other :: Int }
derive instance newtypeSkill :: Newtype Skill _
newtype Feature = Feature { name :: String, something :: Boolean }
derive instance newtypeFeature :: Newtype Feature _
newtype Special = Special { name :: String, different :: String }
derive instance newtypeSpecial :: Newtype Special _

type Namable = forall r. { name :: String | r }

changeModel ::forall p m. Newtype m p => (p -> p) -> m -> m
changeModel f m = over wrap f m

changeName :: forall m. Newtype m Namable => String -> m -> m
changeName newName m = changeModel (\x -> x { name = newName }) m

fishing :: Skill
fishing = Skill { name : "Fishing", other : 2 }

skating = changeName "Skating" fishing

changeModel 函数现在对 Newtype 类型完全通用。 changeName现在就像函数应用一样简单。

详情:

因为我正在使用 Newtype (also look at this info,所以我可以免费获得 overwrap 之类的东西。

over 函数很难理解,因为这些示例是以无意义的风格编写的。

wrap函数returns类型构造器。

lambda 函数是 "what you want done to the data of your newtype"。

末尾的 m 是您传入的实际值。这是被解包并传递到您的 lambda 中的值。