Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 哈斯克尔镜头教程与导线_Haskell_Haskell Lens_Lenses - Fatal编程技术网

Haskell 哈斯克尔镜头教程与导线

Haskell 哈斯克尔镜头教程与导线,haskell,haskell-lens,lenses,Haskell,Haskell Lens,Lenses,我将尝试遵循本教程: 我正在使用加载到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) ->

我将尝试遵循本教程:

我正在使用加载到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
无法推断使用“遍历”产生的(应用程序f)
从上下文(函子f)
由上下文所需的类型绑定:
函子f=>([Post]->f[Post])->[User]->f[User]
时间:58:1-27
可能的解决方案:
将(应用程序f)添加到
上下文所需的类型:
函子f=>([Post]->f[Post])->[User]->f[User]
在“(.”的第一个参数中,即“traverse”
在“view”的第一个参数中,即“(transverse.posts)”中
在表达式中:view(transverse.posts)users

我看到Lens有一个Functor的类型约束,而traverse在f上有一个更为约束的类型约束作为应用程序。这到底是为什么不起作用?为什么博客教程建议它起作用?

视图实际上有一种比
Lens s s t a b->s->a
限制性更小的类型

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

:t view
view :: ((a1 -> Const a1 b1) -> t -> Const a b) -> t -> a
这限制性较小,因为必须为所有
函子定义
透镜
,而要查看的第一个参数只需要为
常量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

如果您删除
镜头
镜头
视图
的定义,而从
控件.Lens
导入它们,它会起作用,尽管这仍然会留下为什么您的镜头不起作用的问题。