- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
不确定我是否在标题中正确地表述了问题,但我正在尝试做这样的事情:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
module Lib where
import Control.Lens
data Foo = Foo {_bar1 :: Int
,_bar2 :: String
,_bar3 :: [Rational]} deriving (Show, Eq)
makeFieldsNoPrefix ''Foo
aFoo :: Foo
aFoo = Foo 33 "Hm?" [1/6,1/7,1/8]
stringToLens :: (HasBar1 s a, Functor f, HasBar2 s a, HasBar3 s a) => String -> Maybe ((a -> f a) -> s -> f s)
stringToLens str = case str of
"bar1" -> Just bar1
"bar2" -> Just bar2
"bar3" -> Just bar3
_ -> Nothing
updateFoo :: (HasBar1 a1 a2, HasBar2 a1 a2, HasBar3 a1 a2, Read a2) => String -> String -> a1 -> Maybe a1
updateFoo lensStr valStr myFoo = case stringToLens lensStr of
Just aLens -> Just $ set aLens (read valStr) myFoo
Nothing -> Nothing
newFoo :: Maybe Foo
newFoo = updateFoo "bar1" 22 aFoo
{--
Couldn't match type ‘[Char]’ with ‘Int’
arising from a functional dependency between:
constraint ‘HasBar2 Foo Int’ arising from a use of ‘updateFoo’
instance ‘HasBar2 Foo String’
at /home/gnumonic/Haskell/Test/test/src/Lib.hs:14:1-24
• In the expression: updateFoo "bar1" 22 aFoo
In an equation for ‘newFoo’: newFoo = updateFoo "bar1" 22 aFoo
--}
(在这里忽略 read 的使用,我在我正在处理的实际模块中以“正确的方式”这样做。)
显然,这行不通。我认为按照以下方式制作类型类可能会奏效:
class OfFoo s a where
ofFoo :: s -> a
instance OfFoo Foo Int where
ofFoo foo = foo ^. bar1
instance OfFoo Foo String where
ofFoo foo = foo ^. bar2
instance OfFoo Foo [Rational] where
ofFoo foo = foo ^. bar3
但似乎没有办法以 stringToLens 函数实际可用的方式将该类添加到约束中,即使在我尝试使用它之前它的类型检查很好。 (尽管如果我使用 makeLenses 而不是 makeFields,它甚至不会进行类型检查,而且我不太确定为什么。)
例如(为简单起见,可能删除了):
stringToLens :: (HasBar1 s a, Functor f, HasBar2 s a, HasBar3 s a, OfFoo s a) => String -> (a -> f a) -> s -> f s
stringToLens str = case str of
"bar1" -> bar1
"bar2" -> bar2
"bar3" -> bar3
这会进行类型检查,但几乎没有用,因为任何应用该函数的尝试都会引发函数依赖性错误。
我还尝试使用 Control.Lens.Reify 中的 Reified 新类型,但这并没有解决函数依赖性问题。
我想不通的是,如果我像这样修改 updateFoo
:
updateFoo2 :: Read a => ASetter Foo Foo a a -> String -> Foo -> Foo
updateFoo2 aLens val myFoo = set aLens (read val) myFoo
然后这个工作:
testFunc :: Foo
testFunc = updateFoo2 bar1 "22" aFoo
但这会在 myLens1
处抛出函数依赖错误,无论何时使用它(尽管定义类型检查):
testFunc' :: Foo
testFunc' = updateFoo2 (stringToLens "bar1") 22 aFoo -- Error on (stringToLens "bar1")
myLens1 :: (HasBar1 s a, Functor f, HasBar2 s a, HasBar3 s a, OfFoo s a) => (a -> f a) -> s -> f s
myLens1 = stringToLens "bar1" -- typechecks
testFunc2 :: Foo
testFunc2 = updateFoo2 myLens1 "22" aFoo -- Error on myLens1
所以我可以定义一个 stringToLens 函数,但它几乎没用......
不幸的是,我写了一堆代码,假设这样的东西可以工作。我正在编写一个数据包生成器,如果我能让它工作,那么我就有了一种非常方便的方法来快速添加对新协议(protocol)的支持。 (我的其余代码广泛使用镜头用于各种目的。)我可以想到一些解决方法,但它们都非常冗长并且需要大量模板 Haskell(为每个新协议(protocol)生成每个函数的副本数据类型)或大量样板文件(即创建虚拟类型以在 updateFoo
函数中为 read
发出正确的类型信号)。
有什么方法可以完成我在这里尝试用镜头做的事情,或者如果没有像命令类型这样的东西是不可能的?如果没有,是否有比我看到的更好的解决方法?
在这一点上,我最好的猜测是没有足够的信息让编译器在没有完全评估的镜头的情况下推断值字符串的类型。
但似乎沿着这些方向的东西应该是可能的,因为当 stringToLens 的输出被传递到 updateFoo 时,它将有一个确定的(和正确的)类型。所以我很难过。
最佳答案
实现 stringToLens
需要依赖类型之类的东西,因为生成的 Lens
的类型取决于参数的值:字段名。 Haskell 没有完整的依赖类型,尽管它们可以是 emulated有或多或少的困难。
在 updateFoo
中,您将字段名称 (lensStr
) 和字段值的“序列化”形式 (valStr
) 作为参数), 并返回某个数据类型的更新函数。我们可以在不依赖的情况下拥有它吗?
想象一下,对于某种类型 Foo
,您有类似 Map FieldName (String -> Maybe (Foo -> Foo))
的东西。对于每个字段名称,您将拥有一个解析字段值的函数,如果成功,则返回 Foo
的更新函数。不需要依赖类型,因为每个字段值的解析将隐藏在具有统一签名的函数后面。
如何为给定类型构建这样的解析器返回更新器映射?您可以手动构建它,也可以在一些 generics 的帮助下派生它wizardry .
这是一个基于 red-black-record 的可能实现库(尽管最好将其基于更成熟的 generics-sop )。一些初步进口:
{-# LANGUAGE DeriveGeneric, FlexibleContexts, FlexibleInstances, #-}
{-# LANGUAGE TypeApplications, TypeFamilies, TypeOperators, ScopedTypeVariables #-}
import qualified Data.Map.Strict as Map
import Data.Map.Strict
import Data.Monoid (Endo (..))
import Data.Proxy
import Data.RBR
( (:.:) (Comp),
And,
Case (..),
FromRecord (fromRecord),
I (..),
IsRecordType,
K (..),
KeyValueConstraints,
KeysValuesAll,
Maplike,
Record,
ToRecord (toRecord),
collapse'_Record,
cpure'_Record,
injections_Record,
liftA2_Record,
unI,
)
import GHC.Generics (Generic)
import GHC.TypeLits
实现本身:
type FieldName = String
type TextInput = String
makeUpdaters ::
forall r c.
( IsRecordType r c, -- Is r convertible to the rep used by red-black-record?
Maplike c, -- Required for certain applicative-like operations over the rep.
KeysValuesAll (KeyValueConstraints KnownSymbol Read) c -- Are all fields readable?
) =>
Proxy r ->
Map FieldName (TextInput -> Maybe (r -> r))
makeUpdaters _ =
let parserForField :: forall v. Read v
=> FieldName -> ((,) FieldName :.: (->) TextInput :.: Maybe) v
parserForField fieldName = Comp (fieldName, Comp read)
parserRecord = cpure'_Record (Proxy @Read) parserForField
injectParseResult ::
forall c a.
Case I (Endo (Record I c)) a -> -- injection into the record
((,) FieldName :.: (->) TextInput :.: Maybe) a -> -- parsing function
(FieldName, Case I (Maybe (Endo (Record I c))) TextInput)
injectParseResult (Case makeUpdater) (Comp (fieldName, Comp readFunc)) =
( fieldName,
( Case $ \textInput ->
let parsedFieldValue = readFunc . unI $ textInput
in case parsedFieldValue of
Just x -> Just $ makeUpdater . pure $ x
Nothing -> Nothing ) )
collapsed :: [(FieldName, Case I (Maybe (Endo (Record I c))) TextInput)]
collapsed = collapse'_Record $
liftA2_Record
(\injection parser -> K [injectParseResult injection parser])
injections_Record
parserRecord
toFunction :: Case I (Maybe (Endo (Record I c))) TextInput
-> TextInput -> Maybe (r -> r)
toFunction (Case f) textInput = case f $ I textInput of
Just (Endo endo) -> Just $ fromRecord . endo . toRecord
Nothing -> Nothing
in toFunction <$> Map.fromList collapsed
测试它的类型:
data Person = Person {name :: String, age :: Int} deriving (Generic, Show)
-- let updaters = makeUpdaters (Proxy @Person)
--
instance ToRecord Person
instance FromRecord Person
关于haskell - 为给定的数据类型编写一个在镜头上具有多态性的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63625905/
在下面的代码中,我得到一个 uninitialized value警告,但仅限于第二个 given/when例子。为什么是这样? #!/usr/bin/env perl use warnings; u
整个“开关”功能是否已成为实验性的?在没有 Perl 的 future 版本破坏我的代码的情况下,我可以依赖其中的某些部分吗?一般来说,将稳定功能更改为实验性的政策是什么? 背景use feature
有没有办法在一个条件语句中写出如下语句? a和b不能同时等于5。 (a可以是5,b可以是5,但是a AND b不能是5) 最佳答案 正如克里斯指出的那样,您要查找的是逻辑异或,相当于逻辑不等于 !=:
我正在寻找一种算法来找到给定 n 条线段的所有交点。以下是来自 http://jeffe.cs.illinois.edu/teaching/373/notes/x06-sweepline.pdf 的伪
数组中有 N 个元素。我可以选择第一项最多 N 次,第二项最多选择 N-1 次,依此类推。 我有 K 个 token 要使用并且需要使用它们以便我可以拥有最大数量的项目。 arr = [3, 4, 8
我正在尝试修复法语文本中的语法性别,想知道是否有办法从某个词条中获取所有单词的列表,以及是否可以在此类列表中进行查找? 最佳答案 尝试: import spacy lemma_lookup = spa
我正在为 Win32 编写一个简单的自动化测试应用程序。它作为一个单独的进程运行,并通过 Windows API 访问目标应用程序。我可以阅读窗口层次结构,查找标签和文本框,并通过发送/发布消息等来单
在 nodeJs 中使用 Sequelize 时,我从 Sequelize 收到此错误,如下所示: { [SequelizeUniqueConstraintError: Validation erro
本文https://arxiv.org/pdf/1703.10757.pdf使用回归激活映射 (RAM) - 而不是类激活映射 (CAM) 来解决问题。有几篇文章描述了如何实现 CAM。但是我找不到
我正在研究 Mach 动态链接器 dyld。这个问题适用于所有 Apple 平台,但很高兴得到特定于平台的答案;我正在使用 ObjC,但如果对你有用的话,我也很乐意翻译 Swift。 The rele
我有一个包含数千个 Instagram 用户 ID 的列表。我如何获得他们的 Instagram 用户名/句柄? 最佳答案 你必须使用这个 Instagram API: https://api.ins
我在下面的代码: def main(args: Array[String]) { val sparkConf = new SparkConf().setAppName("Spark-Hbase").s
我有一个表格,其中包含从 1 到 10 的数字。(从 D2 到 M2) 假设A1中有03/09/2019 并且在B1中有06/09/2019 并且在C1中有Hello 在A 列中,我有多个系列的单词,
我想在给定服务对应的 URI 的情况下检索服务的注释(特别是 @RolesAllowed )。这是一个例子: 服务: @GET @Path("/example") @RolesAllowed({ "B
我看到 OraclePreparedStatementexecuteQuery() 表现出序列化。也就是说,我想使用相同的连接对 Oracle 数据库同时运行两个查询。然而,OraclePrepare
import java.util.Scanner; public class GeometricSumFromK { public static int geometricSum(int k,
我创建了一个抽象基类Page,它说明了如何构建动态网页。我正在尝试想出一种基于作为 HttpServletRequest 传入的 GET 请求生成 Page 的好方法。例如... public cla
我的字符串是一条短信,采用以下两种格式之一: 潜在客户短信: 您已收到 1 条线索 标题:我的领导 潜在客户 ID:12345-2365 警报设置 ID:890 短信回复: 您已收到 1 条回复 标题
我在 python 中有以下代码: class CreateMap: def changeme(listOne, lisrTwo, listThree, listFour, listfive):
这是在 Hibernate 上运行的 JPA2。 我想检索相同实体类型的多个实例,给定它们的 ID。其中许多已经在持久性上下文和/或二级缓存中。 我尝试了几种方法,但似乎都有其缺点: 当我使用 ent
我是一名优秀的程序员,十分优秀!