- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
是否有模仿 SYB 的 generics-sop
/everywhere
行为的 mkT
示例?
我正在尝试做的,但没有看到如何成功地做到这一点,是将 everywhere (mkT fixupSymbol)
中的 main
替换为等效的 Generics.SOP
构造,即,使用 Generics.SOP
递归到产品 (I (AbsAddr value))
并将其替换为 (I (SymAddr label))
。
我可以将符号表传递给 gformatOperands
,从而污染 formatOperands
签名。这似乎不是最理想的。
如果没有 fixupSymbol
,输出将如下所示:
LD B, 0x0000
LD C, 0x1234
CALL 0x4567
gensop % stack ghci
Using main module: 1. Package `gensop' component exe:gensop with main-is file: <...>/Main.hs
gensop-0.1: configure (exe)
Configuring gensop-0.1...
gensop-0.1: initial-build-steps (exe)
Configuring GHCi with the following packages: gensop
GHCi, version 8.6.3: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( <...>/Main.hs, interpreted )
*Main> main
LD B, 0x0000
LD C, label1
CALL label2
*Main>
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Main where
import Data.Data
import Data.Foldable (foldl)
import Data.Word (Word8, Word16)
import Data.Text (Text)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Text.Printf
import Generics.SOP
import Generics.SOP.TH (deriveGeneric)
import Data.Generics.Aliases (mkT)
import Data.Generics.Schemes (everywhere)
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as H
import Data.Sequence (Seq, (|>))
import qualified Data.Sequence as Seq
type Z80addr = Word16
type Z80word = Word8
class Z80operand x where
formatOperand :: x -> Text
main :: IO()
main = mapM_ T.putStrLn (foldl printIns Seq.empty $ everywhere (mkT fixupSymbol) insnSeq)
-- -------------------------------------------------^ Does this have a Generics.SOP equivalent?
where
printIns accum ins = accum |> T.concat ([mnemonic, gFormatOperands] <*> [ins])
mnemonic (LD _) = "LD "
mnemonic (CALL _) = "CALL "
-- Generics.SOP: Fairly straightforward
gFormatOperands {-elt-} =
T.intercalate ", " . hcollapse . hcmap disOperandProxy (mapIK formatOperand) . from {-elt-}
where
disOperandProxy = Proxy :: Proxy Z80operand
-- Translate an absolute address, generally hidden inside an instruction operand, into a symbolic address
-- if present in the symbol table.
fixupSymbol addr@(AbsAddr absAddr) = maybe addr SymAddr (absAddr `H.lookup` symtab)
fixupSymbol other = other
insnSeq :: Seq Z80instruction
insnSeq = Seq.singleton (LD (Reg8Imm B 0x0))
|> (LD (Reg8Indirect C (AbsAddr 0x1234)))
|> (CALL (AbsAddr 0x4567))
symtab :: HashMap Z80addr Text
symtab = H.fromList [ (0x1234, "label1"), (0x4567, "label2")]
-- | Symbolic and absolute addresses. Absolute addresses can be translated into symbolic
-- labels.
data SymAbsAddr = AbsAddr Z80addr | SymAddr Text
deriving (Eq, Ord, Typeable, Data)
data Z80reg8 = A | B | C
deriving (Eq, Ord, Typeable, Data)
-- | Cut down version of the Z80 instruction set
data Z80instruction = LD OperLD | CALL SymAbsAddr
deriving (Eq, Ord, Typeable, Data)
-- | Load operands
data OperLD = Reg8Imm Z80reg8 Z80word | Reg8Indirect Z80reg8 SymAbsAddr
deriving (Eq, Ord, Typeable, Data)
$(deriveGeneric ''SymAbsAddr)
$(deriveGeneric ''Z80reg8)
$(deriveGeneric ''Z80instruction)
$(deriveGeneric ''OperLD)
instance Z80operand Z80word where
formatOperand word = T.pack $ printf "0x%04x" word
instance Z80operand SymAbsAddr where
formatOperand (AbsAddr addr) = T.pack $ printf "0x04x" addr
formatOperand (SymAddr label) = label
instance Z80operand Z80reg8 where
formatOperand A = "A"
formatOperand B = "B"
formatOperand C = "C"
instance Z80operand OperLD where
formatOperand (Reg8Imm reg imm) = T.concat [formatOperand reg, ", ", formatOperand imm]
formatOperand (Reg8Indirect reg addr) = T.concat [formatOperand reg, ", ", formatOperand addr]
gensop.cabal
文件:
cabal-version: >= 1.12
name: gensop
version: 0.1
build-type: Simple
author: scooter-me-fecit
description: No description.
license: GPL-3
executable gensop
default-language: Haskell2010
main-is: Main.hs
build-depends:
base,
containers,
bytestring,
generics-sop,
syb,
text,
unordered-containers
default-extensions:
OverloadedStrings,
FlexibleInstances
ghc-options: -Wall
最佳答案
generics-sop
没有为递归遍历方案提供等价物,例如这些函数。如果您需要在这个库中处理递归,可能的解决方案是实现它们。虽然,在 SOP 中定义这样的函数会带来一些困难,因为它对数据有一个核心的通用 View ,不区分递归节点和叶子。可以使用封闭类型族 (CTF) 和某些类型类机制来管理此设置中的递归。封闭型系列允许您:
mkT
所必需的, generics-sop
图书馆作为案例研究;它提供了在 SOP 中定义递归方案的示例。
everywhere
支持相互递归的数据类型族。以下实现允许将它们指定为类型级列表。
{-# LANGUAGE DeriveGeneric, TypeFamilies, DataKinds,
TypeApplications, ScopedTypeVariables, MultiParamTypeClasses,
ConstraintKinds, FlexibleContexts, AllowAmbiguousTypes,
FlexibleInstances, UndecidableInstances,
UndecidableSuperClasses, TypeOperators, RankNTypes #-}
import Generics.SOP
import Generics.SOP.NS
import GHC.Exts (Constraint)
import Data.Type.Equality
type family Equal a x :: Bool where
Equal a a = 'True
Equal _ _ = 'False
class DecideEq (eq :: Bool) (a :: *) (b :: *) where
decideEq :: Maybe (b :~: a)
instance a ~ b => DecideEq True a b where
decideEq = Just Refl
instance DecideEq False a b where
decideEq = Nothing
type ProofCast a b = DecideEq (Equal a b) a b
castEq :: forall a b. ProofCast a b => b -> Maybe a
castEq t = (\d -> castWith d t) <$> decideEq @(Equal a b)
type Transform a b = (Generic a, Generic b, ProofCast a b, ProofCast b a)
mkT :: Transform a b => (a -> a) -> b -> b
mkT f x = maybe x id $ castEq =<< f <$> castEq x
type family In (a :: *) (fam :: [*]) :: Bool where
In a ([a] ': fam) = 'True
In [a] (a ': fam) = 'True
In a (a ': fam) = 'True
In a (_ ': fam) = In a fam
In _ '[] = 'False
class CaseEverywhere' (inFam :: Bool) (c :: * -> Constraint)
(fam :: [*]) (x :: *) (y :: *) where
caseEverywhere' :: (forall b . c b => b -> b) -> I x -> I y
instance c x => CaseEverywhere' 'False c fam x x where
caseEverywhere' f = I . f . unI
instance (c x, Everywhere x c fam) => CaseEverywhere' 'True c fam x x where
caseEverywhere' f = I . f . everywhere @fam @c f . unI
class CaseEverywhere' (In x fam) c fam x y => CaseEverywhere c fam x y
instance CaseEverywhere' (In x fam) c fam x y => CaseEverywhere c fam x y
caseEverywhere :: forall c fam x y . CaseEverywhere c fam x y
=> (forall b . c b => b -> b) -> I x -> I y
caseEverywhere = caseEverywhere' @(In x fam) @c @fam
type Everywhere a c fam =
(Generic a, AllZip2 (CaseEverywhere c fam) (Code a) (Code a))
everywhere :: forall fam c a . Everywhere a c fam
=> (forall b . c b => b -> b) -> a -> a
everywhere f = to . everywhere_SOP . from
where
everywhere_SOP = trans_SOP (Proxy @(CaseEverywhere c fam)) $
caseEverywhere @c @fam f
everywhere
,与 SYB 的相比,额外接受两个类型参数,通过显式类型应用程序传递。第一个将一系列相互递归的数据类型指定为类型列表。遍历将仅将那些类型在该列表中指定的节点视为递归。需要第二个参数来为编译器提供类型转换的“证明”对象。
T
Transform
的同义词约束用于允许其部分应用。
data Company = C [Dept]
data Dept = D Name Manager [SubUnit]
data SubUnit = PU Employee | DU Dept
data Employee = E Person Salary
data Person = P Name Address
data Salary = S Float
type Manager = Employee
type Name = String
type Address = String
class Transform a b => T a b
instance Transform a b => T a b
type CompanyF = '[Company, Dept, SubUnit, Employee]
increase :: Float -> Company -> Company
increase k = everywhere @CompanyF @(T Salary) (mkT (incS k))
incS :: Float -> Salary -> Salary
incS k (Sal s) = Sal (s * (1 + k))
everywhere
/
mkT
函数已准备好在您的代码中使用,但它遗漏了一些
Generic
实例。申请
everywhere
至
insnSeq
, 你需要一个
Generic (Seq Z80instruction)
实例。然而你无法获得它,因为
Data.Sequence
模块不导出它的内部表示。一个可能的修复方法是应用
fmap
到序列。所以现在你可以写:
{-# LANGUAGE TypeApplications #-}
...
type Z80 = '[SymAbsAddr, Z80reg8, Z80instruction, OperLD]
main :: IO()
main = mapM_ T.putStrLn (foldl printIns Seq.empty $
fmap (everywhere @Z80 @(T SymAbsAddr) (mkT fixupSymbol)) insnSeq)
Generic
遍历的所有类型节点的实例,递归和非递归。所以接下来,这需要
Generic
Word8
的实例,
Word16
, 和
Text
.而
Generic Text
可以通过
deriveGeneric
生成实例,其他人不能,因为他们特殊的 GHC 表示。所以你必须手动完成;这个定义很简单:
$(deriveGeneric ''Text)
instance Generic Word8 where
type Code Word8 = '[ '[Word8]]
from x = SOP (Z (I x :* Nil))
to (SOP ((Z (I x :* Nil)))) = x
instance Generic Word16 where
type Code Word16 = '[ '[Word16]]
from x = SOP (Z (I x :* Nil))
to (SOP ((Z (I x :* Nil)))) = x
DerivingVia
可以很好地简化这一点,减少第二个定义。希望通过独立派生的可能性来改进这个有用的功能,因此可以改为:
deriving via Word8 instance Generic Word16
main
产生预期的结果。
关于haskell - Generics.SOP 等效于无处不在/mkT(替代产品),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54877095/
我们突然开始收到 SequelizeConnectionAcquireTimeoutError 2或3周前的日志,我不知道我能做些什么了。 所以显然有一个连接池,当它已满时,之后的所有操作都会超时,因
由于 IE 的原因,我需要构建一个自定义错误,但是,必须尽我所能,使用构造函数检查错误。 customError instanceof CustomError; // false customErro
相当确定 gradle 适合我。几天前启动了一个运行良好的项目。更新了android studio,再次打开项目。我已经尝试了所有我能想到的方法,从删除/更新检查 xml 文件和结构的库。删除 gra
我希望看到 SO 社区对此的回应。我了解 ViewModel 基本上用于将 View 与数据绑定(bind)。当表单提交时,返回(模型绑定(bind))的对象应该是 ViewModel 还是实体?我知
我想知道 NSUserDefaults 对象是否是共享的,并且可以从应用程序委托(delegate)以及我的几个 View Controller 中访问。基本上我需要从应用程序委托(delegate)
将所有 Sql Server 2008 字符串列设为 varchar(max) 是否有任何问题?我允许的字符串大小由应用程序管理。数据库应该只保留我给它的内容。在 Sql Server 2008 中将
因此,我一直在尝试对自定义 WordPress 主题进行一些更改,该主题引入了对仪表板的全面检修。我一直发现我需要修复的原始主题的小问题(导入新帖子时未正确检查重复帖子,未正确存储帖子元数据,未将帖子
我到处都能看到 Open Sans 字体,大多数时候它都非常流畅,即使在 Chrome 中也是如此。但是当我从 adobe typekit 或 google fonts 添加 open sans 到我
我有一个通用 Parameter 接口(interface)及其ParameterImpl 具体类。 T 可以是 float 、长整型、整数或字符串。 public interface Paramet
我正在尝试编写一个简单的 Ubiquity将在 Wolfram Alpha 上运行查询的命令, 并在 Ubiquity 预览对象中显示结果。 我需要设置预览对象的innerHTML。我目前这样做是为了
我有一个完全自定义的 PHP 站点,其中包含大量数据库调用。我刚刚被注入(inject)黑客攻击。下面的这一小段代码出现在我的许多 PHP 页面中。 而且这个看起来不像 SQL 注入(inject)
我有一个 IntelliJ java 项目,我的源文件夹下有一些 HTML 文件模板。该项目已构建并输出到\target\文件夹。 HTML 文件模板也被复制到目标文件夹。 我一直试图从“到处搜索”结
我在尝试让 iCloud 与我的应用程序一起工作时遇到了一些麻烦。我尝试按照 Tim Roadley 的示例 here ,但每当通过 Xcode 启动应用程序时,仍然会显示下面的日志(同步确实可以短暂
我是一名优秀的程序员,十分优秀!