2015-02-14 2 views
2

Предположение:Каковы сходства и различия между объективом в Haskell и использованием ключевой последовательности в 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 данных.

Мы можем получить доступ к вложенной структуры с помощью ключа-последовательности, как это в Clojure:

(def initialState {:score 0 
        :units {:health 10 
          :position {:x 3.5 
             :y 7.0}}}) 

(def health [:units :health]) 

(defn initialState-getter [lens] 
    (get-in initialState lens)) 

(initialState-getter health) 
> 10 

(defn initialState-setter [lens value] 
    (assoc-in initialState lens value)) 

(initialState-setter health 22) 
> {:score 0, :units {:health 22, :position {:y 7.0, :x 3.5}}} 

Здесь мы видим, вложенная структура обновляется с помощью последовательности клавиш.

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

+3

«Clojure избегает системы типов, предпочитая решать проблему с структурами данных» - очень странное утверждение. Структуры данных и функции являются основой системы типов Haskell. Haskell просто требует, чтобы вы доказали, что используете правильный, вместо того, чтобы позволить ему взорваться во время работы. – Carl

+0

Спасибо - это было не очень понятно. В сообществе Clojure есть трюизм, цитируемый «Данные> Функции> Макросы», что означает, что у вас есть выбор в отношении кодирования вашей логики в структурах данных или функциях или макросах, сначала выберите структуры данных, затем функции, а затем макросы, если у вас действительно есть к. Например (: hello {: hello # (println "Hello World")} - это способ кодирования логики для глобальной функции hello. – hawkeye

+0

Я не знаком с ключевыми последовательностями Clojure, но если бы мне пришлось угадать, основное различие заключалось бы в том, что линзы Haskell набираются и статически проверяются во время компиляции, избегая ошибок выполнения. –

ответ

3

Объективы в Haskell не ограничены клавишами. Например, вы можете написать объектив для длины строки:

lengthLens = lens length setLength 

setLength s l = take l s ++ take (l - length s) (repeat '\0') 

ключевые Clojure последовательности ограничены карты/вектор/и т.д. ключи. Я лично не думаю, что это потеря, так как у меня никогда не было необходимости в объективах для не-ключей-подобных геттеров и сеттеров.

Что касается типов и данных, то состав линз в Haskell - это данные, подобные функциям данных. Это похоже на то, как векторы ключей являются данными в Clojure.