2015-02-14 7 views
1

Предположения:Каковы сходства и различия между объективом в Haskell и деструктурированием в Clojure?

  • Я хочу, чтобы разобрать вложенную JSON строку.
  • Я знаю, что Haskell поощряет решение проблем с системой типов, а Clojure избегает системы типов, предпочитая решать проблему с структурами данных.
  • Я знаю, что на обоих языках этот процесс называется уничтожение того, - но это не имеет другое имя в Clojure, в то время как в Haskell это также называется с помощью линзы, так что я звоню Clojure один уничтожение того, и перемещение на

мы можем видеть, что мы можем создать lenslike this в Haskell:

{-# LANGUAGE TemplateHaskell #-} 

import Control.Lens 

initialState :: Game 
initialState = Game 
    { _score = 0 
    , _units = 
     [ Unit 
      { _health = 10 
      , _position = Point { _x = 3.5, _y = 7.0 } 
      } 
     ] 
    } 

health :: Lens' Unit Int 
health = lens _health (\unit v -> unit { _health = v }) 

Это пур поза - получить значение health из структуры данных game.

Мы можем сделать деструктурирующие like this в Clojure:

user=> (def book {:name "SICP" :details {:pages 657 :isbn-10 "0262011530"}}) 
#'user/book 

user=> (let [{name :name {pages :pages isbn-10 :isbn-10} :details} book] 
    (println "name:" name "pages:" pages "isbn-10:" isbn-10)) 
name: SICP pages: 657 isbn-10: 0262011530 

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

В обоих случаях вы получаете механизм для повторного использования значений из вложенной структуры.

Мой вопрос: Каковы сходства и различия между объективом в Haskell и разрушением в Clojure?

+0

Деструктурирование Clojure на самом деле более похоже на сопоставление образцов в Haskell. – mdorman

ответ

3

Ваш код Clojure будет наиболее точно выразить, как это в Haskell:

book :: Book 
book = Book {name = "SICP", details = Details {pages = 657, isbn_10: "0262011530"}} 

main = do 
    let Book {name = name, details = Details {pages = pages, isbn_10 = isbn_10}} = book 
    putStrLn $ "name:" ++ name ++ "pages:" ++ (show pages) ++ "isbn-10:" ++ isbn-10 

Здесь мы использовали сопоставление с образцом Haskell, которая является в основном более общий вид деструктурирующего связывают Clojure в, чтобы получить на содержимое запись. Это не имеет ничего общего с линзами.

Теперь давайте посмотрим на ваш код Haskell с объективами. Этот код имеет три типа записей: Game, Unit и Point, и каждый из этих типов имеет автоматически определенный набор функций для доступа к своим членам без соответствия шаблону. Эти функции называются _score, _health, _x и т. Д. (Как и имена участников). Они берут Game, Unit или Point соответственно и производят значение их соответствующего члена. Если эти функции должны быть определены вручную (что они делают не потому, что Haskell определяет такие функции для всех типов записей автоматически), это было бы выглядеть следующим образом:

_health (Unit {health = h}) = h 

До сих пор это еще не имеет ничего общего с линзы.

Линза в коде health.Он содержит функцию _health (которая, как описано, принимает Unit и производит ее работоспособность) и функцию (\unit v -> unit { _health = v }), которая берет единицу и значение и производит новый блок, чье здоровье установлено на это значение. Другими словами, объектив содержит код для получения и настройки работоспособности устройства. Библиотека Lens теперь содержит различные функции, которые вы можете использовать для создания и работы с такими объективами.

Итак, чтобы ответить на ваш вопрос: между объективами и разрушением нет никаких сходств.

+0

Да - справедливо - я дам вам это. Я чувствую, что я не задал вопрос правильно. Я думаю, что у меня в голове был вопрос: «В чем разница между объективом в Haskell и использованием ключевой последовательности для доступа к вложенной структуре в Clojure?» например: https://gist.github.com/anonymous/240e024625923d99cfd6 – hawkeye

 Смежные вопросы

  • Нет связанных вопросов^_^