Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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 我如何处理“;typedef”-使用最少的样板文件设置数据类型的样式?_Haskell - Fatal编程技术网

Haskell 我如何处理“;typedef”-使用最少的样板文件设置数据类型的样式?

Haskell 我如何处理“;typedef”-使用最少的样板文件设置数据类型的样式?,haskell,Haskell,我定义了一个包含单个字段的自定义数据类型: import Data.Set (Set) data GraphEdge a = GraphEdge (Set a) 定义我自己的类型在语义上更为正确,但这会导致函数中出现大量样板文件。每当我想使用内置的Set功能时,我都必须打开内部集合,然后重新包装它: import Data.Set (map) modifyItemsSomehow :: Ord a => GraphEdge a -> GraphEdge a modifyItem

我定义了一个包含单个字段的自定义数据类型:

import Data.Set (Set)

data GraphEdge a = GraphEdge (Set a)
定义我自己的类型在语义上更为正确,但这会导致函数中出现大量样板文件。每当我想使用内置的
Set
功能时,我都必须打开内部集合,然后重新包装它:

import Data.Set (map)

modifyItemsSomehow :: Ord a => GraphEdge a -> GraphEdge a
modifyItemsSomehow (GraphEdge items) = GraphEdge $ Set.map someFunction items
这可以通过创造一个记录来稍微改进,比如

import Data.Set (Set, map)

data GraphEdge a = GraphEdge { unGraphEdge :: Set a }

modifyItemsSomehow = GraphEdge . map someFunction . unGraphEdge

但这仍然感觉很不理想。在处理由单个字段组成的用户定义的数据类型时,处理此类样板文件的最惯用方法是什么?

在执行任何其他操作之前,应确保对单个字段的单个构造函数类型使用
newtype
<代码>数据引入了运行时开销和额外的惰性,并阻止我们使用以下前两种技术

首先,您可以在可能的情况下使用:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Foo a = Foo a deriving (Eq, Show, Ord, Num)

foo :: Foo Int
foo = 0

bar :: Foo Int
bar = foo * 120
其次,您可以使用在新类型包装之间进行转换:

import Data.Coerce

newtype Foo a = Foo a
newtype Bar a = Bar a

a :: [(Foo (Bar Int), Foo ())]
a = [(Foo (Bar 0), Foo ())]

b :: [(Int, ())]
b = coerce a
第三,可以使用-s from在newtype构造函数上/下简洁地移动操作

{-# LANGUAGE TemplateHaskell #-}

import Data.Set (Set)
import qualified Data.Set as Set
import Control.Lens

newtype GraphEdge a = GraphEdge (Set a)
makePrisms ''GraphEdge

modifyItemsSomehow :: Ord a => GraphEdge a -> GraphEdge a
modifyItemsSomehow = _GraphEdge %~ Set.map someFunction

你用
数据
而不是
新类型
的任何原因?@Carl不,只是无知:-)
镜头
现在提供了(仅限7.10+版本;不知道为什么不是7.8-可能是我的错误)
强制::所有的都不是b。(可强制s a,可强制t b)=>Iso s t a b
lens
还提供了
控件.lens.Wrapped
模块,用于在新类型下执行各种形式的操作。