2

假设:

  • 我知道 Haskell 鼓励用类型系统解决问题,而 Clojure 避开类型系统,更喜欢用数据结构解决问题。

我们可以看到我们可以在 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 中使用键序列之间有什么异同?

4

1 回答 1

3

Haskell 中的镜头不仅限于键。例如,您可以为字符串的长度编写一个镜头:

lengthLens = lens length setLength

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

Clojure 键序列仅限于 map/vector/etc 键。我个人不认为这是一种损失,因为我从来不需要用于非键式吸气剂和二传手的镜头。

至于类型与数据,Haskell 中的镜头组合是数据,就像函数是数据一样。这类似于 Clojure 中键向量是数据的方式。

于 2015-02-15T10:20:59.547 回答