Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.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 - Fatal编程技术网

Haskell 有这样的标准抽象吗?(又名猜测结构)

Haskell 有这样的标准抽象吗?(又名猜测结构),haskell,Haskell,我在重构一个爱好项目时提出了以下结构。我想知道它是否匹配,或者可以调整以匹配现有的抽象/结构。我开始阅读Applicative、Functor和Arrows,但无法建立联系,我也没有更多的想法。因此,最简单的有用示例是: -- trivial struct for this minimal example data T = T { n :: Int, s :: String } -- for any type `a`, there's exactly one way to update a `

我在重构一个爱好项目时提出了以下结构。我想知道它是否匹配,或者可以调整以匹配现有的抽象/结构。我开始阅读Applicative、Functor和Arrows,但无法建立联系,我也没有更多的想法。因此,最简单的有用示例是:

-- trivial struct for this minimal example
data T = T { n :: Int, s :: String }

-- for any type `a`, there's exactly one way to update a `T`
class Gen a where
  gen :: a -> T -> T

-- helpers to compose `a`-s into a (T -> T)
(.>) :: (Gen a) => (T -> T) -> a -> (T -> T)
l .> x = l . (gen x)

(<.>) :: (Gen a, Gen b) => a -> b -> T -> T
l <.> r = (gen l) . (gen r)

-- For this example, let's say an Int is used to update a T by adding to its `n`
instance Gen Int where
  gen x t = t { n = (n t) + x }

-- and a Char is prepended to its `s`
instance Gen Char where
  gen c t = t { s = c : (s t) }

-- I can now express things like this easily
appendFooAndAdd3 = 'F' <.> 'o' .> 'o' .> (3::Int)
实际代码,以防更多上下文有用:

如果你能找到一些可以在这里使用的结构,如果你能解释一下你是如何得出结论的,我将不胜感激。我想我可以从中学到很多东西


编辑:澄清我的问题:这可以通过使用一些现有的抽象来实现吗?Applicative和Functor是我的意思的例子,但它们似乎不符合这种情况。如果是的话,您是如何建立该结构的?

因此,我查阅了的文档,以了解如何做到这一点。这似乎是惯用的方式:

{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Lens.TH

data T = T
    { _n :: Int
    , _s :: String
    } deriving (Eq, Ord, Read, Show)

makeLenses ''T

appendFooAndAdd3 = (s <>~ "Foo") . (n +~ 3)
您会注意到,在您的方法中,事情并不是那么隐含:在s~Foo中,必须命名字段s和要执行的操作,在n+~3中也是如此。然而,这可能被视为一种优势,因为只有一种方法可以修改T


在这种情况下,我认为Pythonism显式优于隐式应用。

因此,我查阅了的文档,以了解如何做到这一点。这似乎是惯用的方式:

{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
import Control.Lens.TH

data T = T
    { _n :: Int
    , _s :: String
    } deriving (Eq, Ord, Read, Show)

makeLenses ''T

appendFooAndAdd3 = (s <>~ "Foo") . (n +~ 3)
您会注意到,在您的方法中,事情并不是那么隐含:在s~Foo中,必须命名字段s和要执行的操作,在n+~3中也是如此。然而,这可能被视为一种优势,因为只有一种方法可以修改T


在这种情况下,我认为Pythonism显式优于隐式。

。。。。你的问题是什么?现在还不太清楚您需要什么帮助。添加了一个编辑来澄清它。通常,当使用多态容器时,应用程序和functor之类的东西很有用,但是您的类型只是一个简单的旧数据类型,没有多态性,这里可能没有太多您可以抽象的内容。您可以使用FlexibleContexts和MultiparamTypeClass将其编写为类Gen a t,其中Gen::a->t->t这看起来很像一个广义的cons类型,然后使用相同的定义追加FoodAndAdd3::Gen Char t,Gen Int t=>t->t,然后它可以与更多类型一起使用,而不仅仅是t,但你可能会遇到重叠的实例问题。也许吧。我只是想补充一句,几个月前我问了一个类似的问题,尽管我的思维过程没有你想象的那么快,镜头绝对是你想要的。如果你想了解镜头背后的理论,那么这段视频是令人惊奇的:如果你只是想快速开始检查或接受我的问题的答案,那么。。。。你的问题是什么?现在还不太清楚您需要什么帮助。添加了一个编辑来澄清它。通常,当使用多态容器时,应用程序和functor之类的东西很有用,但是您的类型只是一个简单的旧数据类型,没有多态性,这里可能没有太多您可以抽象的内容。您可以使用FlexibleContexts和MultiparamTypeClass将其编写为类Gen a t,其中Gen::a->t->t这看起来很像一个广义的cons类型,然后使用相同的定义追加FoodAndAdd3::Gen Char t,Gen Int t=>t->t,然后它可以与更多类型一起使用,而不仅仅是t,但你可能会遇到重叠的实例问题。也许吧。我只是想补充一句,几个月前我问了一个类似的问题,尽管我的思维过程没有你想象的那么快,镜头绝对是你想要的。如果你想了解镜头背后的理论,那么这段视频是令人惊奇的:如果你只是想快速开始检查或接受我的问题的答案