Как мне работать с определенными группами новичков - PullRequest
0 голосов
/ 01 июля 2018

Я пытаюсь заставить работать следующее, но я не могу понять, что это правильно. Я ожидаю, что что-то вроде этого будет работать:

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 определение.

1 Ответ

0 голосов
/ 01 июля 2018

Похоже, мне нужен был класс типов 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 (также посмотрите эту информацию Я получаю такие вещи, как over и wrap бесплатно.

Функцию over очень сложно понять, поскольку примеры написаны в стиле без точек.

Функция wrap возвращает конструктор типа.

Лямбда-функция - это «то, что вы хотите сделать с данными вашего нового типа».

m в конце - это фактическое значение, которое вы передаете. Это значение, которое распаковывается и передается в вашу лямбду.

...