标签: lenses

通过 DCG 在 Prolog 中使用镜头,可能与否?

在 Prolog 中玩弄镜头。镜头是一种显微镜,可以放大结构并以功能方式进行一些读取或写入。基本上我的出发点是以下 Prolog 中 setter 和声明性 getter 的建模:

消气:只是<closure>
被称为call(<closure>, X, Y),这将检索该值YX

声明式设置器:相同<closure>但使用不同的元数,
称为 as call(<closure>, X, Y, Z),这将X通过一个新值更新 并Y给出一个新的Z

我很快就得出了镜头合成运算符 @ 的定义,它可用于将两个镜头组合成一个新镜头,仅基于它们的闭合。附录中提供了一个示例和定义。但根据这篇文章,镜头可以简单地合成。

在我看来,当某些东西是合成的时,它可以很容易地通过 DCG 建模。我可以按如下方式为 getter 执行此操作,但我还没有找到为声明性 setter 执行此操作的方法:

/* Getter composition as DCG */
@(C1, C2) --> 
     call(C1),
     call(C2).
Run Code Online (Sandbox Code Playgroud)

我将如何在 DCG 中对 setter 组合进行建模?这是可能的,也许会改变 getter 和 declarative setter 如何建模的初始假设,以便结果只是组合?

此致

附录:以下是一些 setter 和 getter 的示例:

/* …
Run Code Online (Sandbox Code Playgroud)

functional-programming prolog composition lenses dcg

5
推荐指数
1
解决办法
182
查看次数

有没有办法将 circe-optics 的 JsonPath 与字符串一起使用,就像在 jq CLI 工具中一样?

我想做的是将字段描述符定义为json 的field1.field2[1].field3访问值two

{
  "field1": {
    "field2": [
      {
        "field3": "one"
      },
      {
        "field3": "two"
      }
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用applyDynamicand做到这一点root.field1.field2.index(1).field3,但是有没有办法使用字符串来创建这样的镜头?

json scala lenses monocle-scala circe

5
推荐指数
0
解决办法
416
查看次数

Haskell - newtype 上的 iso

如果我有一个newtype

newtype Foo = Foo Int
Run Code Online (Sandbox Code Playgroud)

有没有一种自动获取 的方法Iso' Foo Int

我看到我可以使用makeLenses ''Foo,但我不知道生成的 iso 的名称是什么。

haskell lenses haskell-lens

5
推荐指数
1
解决办法
106
查看次数

“Wither”的 Profunctor 表示是什么?

克里斯·彭纳 (Chris Penner) 的这篇文章谈到了“枯萎的光学”;可用于从结构中过滤项目的光学元件。

本文对这些光学器件使用以下“Van Laarhoven”表示:

type Wither s t a b = forall f. Alternative f => (a -> f b) -> s -> f t
Run Code Online (Sandbox Code Playgroud)

大多数(如果不是全部)Van Laarhoven 光学具有等效的 profunctor 表示。例如镜头:

type Lens s t a b = forall f. Functor f => (a -> f b) -> s -> f t 
Run Code Online (Sandbox Code Playgroud)

相当于:

type Lens s t a b = forall p. Strong p => p a b -> p s t
Run Code Online (Sandbox Code Playgroud)

是否Wither也有 Profuctor 代表?如果是这样,那是什么?

haskell lenses profunctor

5
推荐指数
1
解决办法
137
查看次数

如何使用lens访问sum类型后面的记录字段

我正在尝试使用 Haskell 中的透镜和棱镜访问嵌套记录:

import Data.Text (Text)
import Control.Lens.TH

data State = State
    { _stDone :: Bool
    , _stStep :: StateStep
    }

data StateStep
    = StatePause
    | StateRun
        { _stCounter  :: Int
        , _stMMistake :: Maybe Text
        }

makeLenses ''State
makeLenses ''StateStep
makePrisms ''StateStep

main :: IO ()
main = do
    let st = State False $ StateRun 0 Nothing

    -- works, but the `_2` seems weird
        mMistake = st ^? stStep . _StateStepRun . _2 . _Just

    -- why not …
Run Code Online (Sandbox Code Playgroud)

haskell record lenses haskell-lens

5
推荐指数
1
解决办法
383
查看次数

使用Control.Lens编写镜头,必须调用中间函数

假设我有以下内容:

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens

data Book = Book {
  _author :: String,
  _title :: String
} deriving (Show)

makeLenses ''Book

data Location = Location {
  _city :: String,
  _state :: String
} deriving (Show)

makeLenses ''Location

data Library = Library {
  _location :: Location,
  _books :: [Book]
} deriving (Show)

makeLenses ''Library

lib :: Library
lib = Library (Location "Baltimore" "MD") [Book "Plato" "Republic", Book "Aristotle" "Ethics"]
Run Code Online (Sandbox Code Playgroud)

我试图通过组合镜头来了解通过多层向下延伸的各种方法.我知道如何做这些操作:

-- returns "Baltimore"
lib ^. location . city

-- …
Run Code Online (Sandbox Code Playgroud)

haskell functional-programming lenses

4
推荐指数
1
解决办法
453
查看次数

Haskell Control.Lens遍历棱镜

我有一个深度嵌套的数据结构,我正在使用Control.Lens.*来简化在状态monad中访问它的值.

请考虑以下事项:

data Config = Config { _foo :: Maybe Int
                     , _bar :: Int
                     }

$(makeLenses ''Config)
Run Code Online (Sandbox Code Playgroud)

如何在"可爱"上"操作"地操作?我想写一个惯用的吸气剂:

config = Config (Just 1) 0
config^.foo.to fmap (+1) == Just 2
Run Code Online (Sandbox Code Playgroud)

更好的是,当Config嵌套得更深时,我们将如何处理这种情况?

data Config = { _foo :: Maybe Foo }
data Foo = Foo { _bar :: Bar }
data Bar = Bar Int
$(makeLenses ''Bar)
$(makeLenses ''Foo)
Run Code Online (Sandbox Code Playgroud)

我们可以使用访问器foo和bar来返回修改后的Bar吗?

haskell lenses haskell-lens

4
推荐指数
1
解决办法
2073
查看次数

基于Scala类型的属性提取器 - 仅限Getter镜头?

从数据容器(例如案例类)中提取类型的最佳方法是什么.

例如,如果我有type Tagged[U] = { type Tag = U}标记类型trait PID,标记为Int type ProductId = Int with Tagged[PID]或scalaz样式,type ProductId = Int @@ PID并说明产品type Name = String @@ PName等中的其他字段和包含产品属性的数据容器;

case class Product(pid: ProductId, name: Name, weight: Weight)
Run Code Online (Sandbox Code Playgroud)

如何在A => B不诉诸反射的情况下编写通用的提取器样式方法?

原因是我想在运行时从Product容器中动态提取字段.即,用户传递他们想要提取的产品的属性.

即如果我想动态获取ProductId,我可以编写一个接受类型并返回值的方法,例如

trait Extractor[A] {
  def extract[B](i: A): B = //get type B from the Product class
}
Run Code Online (Sandbox Code Playgroud)

或者我是在复杂的事情.

我可以编写简单的提取器类,它采用A => B函数并为每种类型定义它;

trait Getter[A, B] {
  def extract(i: A): B …
Run Code Online (Sandbox Code Playgroud)

generics scala scalaz lenses shapeless

4
推荐指数
1
解决办法
551
查看次数

如何在独立的Getter中使用(^?ix 0)?

抱歉这个措辞不好的标题,但我甚至不知道如何正确地问它.

我怎么能这个呢?

instPublicIP :: Instance -> Maybe Text
instPublicIP inst =
  inst ^. insNetworkInterfaces ^? ix 0 . iniAssociation . _Just . iniaPublicIP . _Just
Run Code Online (Sandbox Code Playgroud)

进入这个

instPublicIP' :: Lens' Instance (Maybe Text)
instPublicIP' = insNetworkInterfaces ^? ix 0 . iniAssociation . _Just . iniaPublicIP . _Just
Run Code Online (Sandbox Code Playgroud)

当我尝试时,我收到以下错误:

Main.hs:198:3:
    Couldn't match expected type ‘(Maybe Text -> f (Maybe Text))
                                  -> Instance -> f Instance’
                with actual type ‘Maybe Text’
    Relevant bindings include
      instPublicIP' :: (Maybe Text -> f (Maybe Text))
                       -> …
Run Code Online (Sandbox Code Playgroud)

haskell lenses haskell-lens

4
推荐指数
1
解决办法
64
查看次数

用镜头刺伤获得价值

我想编写一个函数,在Lens stab的帮助下将函数(a - > b)转换为函数(s - > t)(编辑:我意识到这个函数已经存在Setter s t a b并且被称为over或者%~,但是它没有回答下面使用镜头获取值的问题).看起来很简单,但我遇到了一个令人困惑的类型错误.要创建一个更小的示例,请考虑以下函数,它只返回镜头从第二个参数中提取的值:

f :: Lens s t a b -> s -> a
f l s = s ^. l
Run Code Online (Sandbox Code Playgroud)

这不编译.在^的第二个参数中有2个错误.(即l):

  • 无法将类型't'与's'匹配
  • 无法将类型'a'与'b'匹配

但是,以下编译:

f :: Getter s a -> s -> a
f l s = s ^. l
Run Code Online (Sandbox Code Playgroud)

然后,我意识到在镜头类型层次结构中,Lens和Getter之间的箭头指定s = t,a = b.有没有办法使用常规从Lens s t a b类型a的值中获取类型的值s

haskell lenses haskell-lens

4
推荐指数
1
解决办法
176
查看次数