Haskell 中的镜头与在 Clojure 中使用键序列有何异同?
What are the similarities and differences between a lens in Haskell and using a key-sequence in Clojure?
假设:
- 我知道 Haskell 鼓励用类型系统解决问题,而 Clojure 避开类型系统,更喜欢用数据结构解决问题。
我们可以看到可以在Haskell中创建一个lens like this:
{-# 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 })
它的目的是从 game
数据结构中获取 health
值。
我们可以在 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 中的 lens 与在 Clojure 中使用键序列有何异同?
Haskell中的镜头不限于按键。例如,您可以为字符串的长度编写一个镜头:
lengthLens = lens length setLength
setLength s l = take l s ++ take (l - length s) (repeat '[=10=]')
Clojure 键序列仅限于 map/vector/etc 个键。我个人不认为这是一个损失,因为我从来不需要像非钥匙一样的 getter 和 setter 的镜头。
至于类型与数据,Haskell 中的镜头组合是数据,就像功能是数据一样。这类似于键向量在 Clojure 中的数据。
假设:
- 我知道 Haskell 鼓励用类型系统解决问题,而 Clojure 避开类型系统,更喜欢用数据结构解决问题。
我们可以看到可以在Haskell中创建一个lens like this:
{-# 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 })
它的目的是从 game
数据结构中获取 health
值。
我们可以在 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 中的 lens 与在 Clojure 中使用键序列有何异同?
Haskell中的镜头不限于按键。例如,您可以为字符串的长度编写一个镜头:
lengthLens = lens length setLength
setLength s l = take l s ++ take (l - length s) (repeat '[=10=]')
Clojure 键序列仅限于 map/vector/etc 个键。我个人不认为这是一个损失,因为我从来不需要像非钥匙一样的 getter 和 setter 的镜头。
至于类型与数据,Haskell 中的镜头组合是数据,就像功能是数据一样。这类似于键向量在 Clojure 中的数据。