我有一个包含不同类型字段的记录,以及一个适用于所有这些类型的函数.作为一个小(愚蠢)的例子:
data Rec = Rec { flnum :: Float, intnum :: Int } deriving (Show)
Run Code Online (Sandbox Code Playgroud)
说,我想定义一个每个字段添加两个记录的函数:
addR :: Rec -> Rec -> Rec
addR a b = Rec { flnum = (flnum a) + (flnum b), intnum = (intnum a) + (intnum b) }
Run Code Online (Sandbox Code Playgroud)
有没有办法表达这一点而不重复每个字段的操作(记录中可能有很多字段)?
实际上,我有一个仅由Maybe字段组成的记录,我想将实际数据与包含某些字段的默认值的记录结合起来,以便在实际数据时使用Nothing.
(我想应该可以使用模板haskell,但我对"便携式"实现更感兴趣.)
我有一个具有类似mappend函数但没有实函数的类型mappend,因此它不是Semigroup。例如:
data MyType = MyType Int deriving Show
myMerge :: MyType -> MyType -> Maybe MyType
myMerge (MyType x) (MyType y)
| (x < 0) || (y < 0) = Nothing
| otherwise = Just $ MyType $ x + y
Run Code Online (Sandbox Code Playgroud)
我总是MyType在包裹时处理它Maybe。如果我可以像这样Semigroup在“组合”类型上定义实例,我需要可以完美表示的语义Maybe MyType:
instance Semigroup (Maybe MyType) where
(Just x) <> (Just y) = myMerge x y
Nothing <> Nothing = Nothing
Nothing <> (Just _) …Run Code Online (Sandbox Code Playgroud) 我试图制作一个程序,通过一些第三方模块,依赖于icu库.我怀疑依赖是通过Network.HTTP.Conduit但可能通过其他东西.动态链接的二进制文件即使在相同发行版的相邻版本之间也不可移植,因为libicu*具有不兼容的不同版本.
所以我试图静态地构建程序:
$ ghc --make -static -optc-static -optl-static my-prog.hs -optl-pthread
Run Code Online (Sandbox Code Playgroud)
我收到了很多这样的错误:
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libicuuc.a(dictionarydata.ao):(.data.rel.ro._ZTIN6icu_5222BytesDictionaryMatcherE[_ZTIN6icu_5222BytesDictionaryMatcherE]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libicuuc.a(dictionarydata.ao):(.data.rel.ro._ZTVN6icu_5217DictionaryMatcherE[_ZTVN6icu_5217DictionaryMatcherE]+0x28): undefined reference to `__cxa_pure_virtual'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
我相信我有所有涉及的库的静态版本(libicu,libstdc++).似乎连接器没有提供libstdc++(或者是它libitl?显然在后者中定义了有问题的功能).
我尝试添加选项-optl-static-libstdc++,-optl-lstdc++并-optl-litm在命令行的末尾无济于事.
静态链接间接依赖于C++支持函数的haskell程序的过程是什么?我在跑步
The Glorious Glasgow Haskell Compilation System, version 7.6.3
gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
Run Code Online (Sandbox Code Playgroud)
要么
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2
Run Code Online (Sandbox Code Playgroud)
编辑:
我将问题缩小到包Data.Text.ICU,这是一个无法构建到静态可执行文件中的简短程序:
{-# LANGUAGE OverloadedStrings #-}
module Main where
import …Run Code Online (Sandbox Code Playgroud) 我需要声明具有“复杂”类型的全局变量,并且不应在导入时实例化。在Python 3.6+中,我可以省略初始化,例如:
log: logging.Logger
pollset: select.poll
Run Code Online (Sandbox Code Playgroud)
我需要使代码与 Python 3.5 兼容。我可以使用评论类型注释:
log = ... # type: logging.Logger
pollset = ... # type: select.poll
Run Code Online (Sandbox Code Playgroud)
但随后我必须提供初始值。这在运行时不是问题,分配Noneor的初始值...就可以了。但其中任何一个都会触发 mypy 类型检查错误:
myprog.py:19:错误:赋值中的类型不兼容(表达式的类型为“省略号”,变量的类型为“Logger”)
当然我可以使用Optionaltype 来允许初始化为None,但是类型检查会被削弱。例如,None在代码中的其他地方给变量赋值是非法的,但它不会被捕获。
是否有一种可接受的方法以与 Python 3.5 兼容的方式使用变量的强类型检查?