繁体   English   中英

带有遍历的Haskell镜头教程

[英]Haskell Lens Tutorial with traverse

我正在尝试按照本教程: http//blog.jakubarnold.cz/2014/08/06/lens-tutorial-stab-traversal-part-2.html

我正在使用以下代码加载到ghci中:

{-# LANGUAGE RankNTypes, ScopedTypeVariables  #-}

import Control.Applicative
import Data.Functor.Identity
import Data.Traversable

-- Define Lens type.
type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t 
type Lens' s a = Lens s s a a 

-- Lens view function. Omitting other functions for brevity.
view :: Lens s t a b -> s -> a
view ln x = getConst $ ln Const x

-- Tutorial sample data types
data User = User String [Post] deriving Show
data Post = Post String deriving Show

-- Tutorial sample data
john = User "John" $ map (Post) ["abc","def","xyz"]
albert = User "Albert" $ map (Post) ["ghi","jkl","mno"]
users = [john, albert]

-- A lens
posts :: Lens' User [Post]
posts fn (User n ps) = fmap (\newPosts -> User n newPosts) $ fn ps

从那里,像这样的简单的东西工作:

view posts john

但是,当我尝试执行下一步时,它不起作用:

view (traverse.posts) users

我明白了:

Could not deduce (Applicative f) arising from a use of ‘traverse’
from the context (Functor f)
  bound by a type expected by the context:
             Functor f => ([Post] -> f [Post]) -> [User] -> f [User]
  at <interactive>:58:1-27
Possible fix:
  add (Applicative f) to the context of
    a type expected by the context:
      Functor f => ([Post] -> f [Post]) -> [User] -> f [User]
In the first argument of ‘(.)’, namely ‘traverse’
In the first argument of ‘view’, namely ‘(traverse . posts)’
In the expression: view (traverse . posts) users

我看到Lens具有Functor的类型约束,并且遍历在f上具有更多约束类型约束作为Applicative。 为什么这不起作用,为什么博客教程表明它有效?

view实际上有一个比Lens stab -> s -> a更少限制的类型Lens stab -> s -> a

如果删除类型签名,ghci将告诉您view的类型

:t view
view :: ((a1 -> Const a1 b1) -> t -> Const a b) -> t -> a

这样的限制性较小,因为Lens必须定义为forall函数,而要查看的第一个参数只需要为Const a1定义。

如果我们根据Lens的名称重命名类型变量并限制a1 ~ a这个签名会更有意义

type Lens s t a b = forall f. Functor f =>
         (a -> f       b) -> s -> f       t 
view :: ((a -> Const a b) -> s -> Const a t) -> s -> a
view ln x = getConst $ ln Const x

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM