我正在努力使以下各项起作用,但似乎无法正确解决。我希望像这样的东西能起作用:
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
添加功能。这并不总是完整的集合,也不总是一个以上的集合,但是我想写我定义的类型的实际功能“无知”。如果将来我决定添加一个newtype Statistic
,我希望它“正常工作”。
为了改善这个问题,我想知道我要寻找的签名类型是否有名称?
f :: forall m a. (a -> a) -> m a -> m a
似乎不太通用的Functor
定义。
答案 0 :(得分:1)
好像我需要的是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
(另请参阅this info,所以我免费获得over
和wrap
之类的东西。
over
函数很难理解,因为示例以无点样式编写。
wrap
函数返回类型构造函数。
lambda函数是“您要对新类型的数据执行的操作”。
最后的m
是您要传递的实际值。这是被解包并传递给lambda的值。