女士们,先生们,美好的一天!
我经常编写解析器和编解码器.实现解析器和打印机似乎是大量的代码重复.我想知道是否可以反转有状态计算,因为它本质上是同构的.
可以反转纯函数组合(Control.Lens.也可以通过在同构上定义组合运算符来实现).可以观察到,
Iso bc cb . Iso ab ba = Iso (bc . ab) (ba . cb) -- from Lenses talk
invert (f . g) = (invert g) . (invert f) -- pseudo-code
Run Code Online (Sandbox Code Playgroud)
换句话说,为了反转函数组合,应该以相反的顺序组成反转函数.因此,给定所有原始同构对,可以组合它们以获得更复杂的对,而不需要代码重复.以下是纯双向计算的示例(使用Control.Lens,解释性视频可以帮助您获得镜头,折叠和遍历的一般概念):
import Control.Lens
tick :: Num a => Iso' a a
tick = iso (+1) (subtract 1) -- define an isomorphic pair
double :: Num a => Iso' a a
double = iso (+2) (subtract 2) -- and another one
threeTick :: Num a …Run Code Online (Sandbox Code Playgroud) 我正在尝试将Vim用作Haskell IDE,虽然我不是硬核Vim用户,但我喜欢基于模式的编辑方式.
在我的Emacs时期之后,我唯一缺少的是与GHCi集成.在后一个编辑器中,您只需键入C-c C-l(所有类型的REPL环境的相同快捷方式)即可重新加载当前源文件并切换到包含解释器的拆分窗口.这种可能性对于快速原型设计,TDD等是必不可少的.我确信我已经做了大量工作试图在Vim中获得相同的功能,但没有显着的结果.
如果有人已经处理过这样的任务,请提供解决方案的链接或提示.
美好的一天!
我有一个元素树:
data Tree a = Node [Tree a]
| Leaf a
Run Code Online (Sandbox Code Playgroud)
我需要到达那棵树的叶子.从根到叶的路径由一系列switch函数确定.该树中的每个层对应于一个特定的switch函数,该函数将某些内容作为参数并将索引返回到子树.
class Switchable a where
getIndex :: a -> Int
data SwitchData = forall c. Switchable c => SwitchData c
Run Code Online (Sandbox Code Playgroud)
最终目标是提供一个期望所有必需的函数SwitchData并返回树中的叶子.
但我认为无法在类型级别强制执行一对一映射.我当前的switch
函数实现接受一个SwitchData实例列表:
switch :: SwitchData -> Tree a -> Tree a
switch (SwitchData c) (Node vec) = vec `V.unsafeIndex` getIndex c
switch _ _ = error "switch: performing switch on a Leaf of context tree"
switchOnData :: [SwitchData] …Run Code Online (Sandbox Code Playgroud) haskell ×2
ghci ×1
integration ×1
invert ×1
parsing ×1
polymorphism ×1
state ×1
tree ×1
vim ×1