我有一个类型的功能如下:
union :: a -> a -> a
Run Code Online (Sandbox Code Playgroud)
并a
具有可加性属性.所以我们可以union
视为一个版本(+)
比方说,我们有[a]
并且想要执行并行"folding"
,对于非并行折叠,我们只能这样做:
foldl1' union [a]
Run Code Online (Sandbox Code Playgroud)
但是如何并行执行呢?我可以证明Num
价值和(+)
功能的问题.
例如,我们有一个列表[1,2,3,4,5,6]
,(+)
并且我们应该分开
[1,2,3] (+) [4,5,6]
[1,2] (+) [3] (+) [4,5] (+) [6]
([1] (+) [2]) (+) ([3] (+) [4]) (+) ([5] (+) [6])
Run Code Online (Sandbox Code Playgroud)
然后(+)
我们想要并行执行每个操作,并结合起来回答
[3] (+) [7] (+) [11] = 21
Run Code Online (Sandbox Code Playgroud)
请注意,由于可a
加性,我们拆分列表或以任何顺序执行操作.
有没有办法使用任何标准库?
我的主要功能块中有一个功能
map anyHeavyFunction [list]
Run Code Online (Sandbox Code Playgroud)
我想在计算过程中显示进度条或添加其他操作(暂停,停止进程等),但因为map
是纯函数我不能直接执行.我猜我必须使用monad,但是monad是合适的吗?IO
,State
?
我尝试创建一个用于处理逻辑表达式的数据结构.乍一看,逻辑表达式看起来像Trees
,所以从树上组成它似乎是合理的:
data Property a = And (Property a) (Property a) |
Or (Property a) (Property a) |
Not (Property a) | Property a deriving (Show,Eq)
Run Code Online (Sandbox Code Playgroud)
但这不是一个好主意,因为我的树的左右分支之间确实没有区别,因为 A && B == B && A
好吧,也许List
更好?
data Property a = Empty | And a (Property a) | Or a (Property a) | Not a (Property a) deriving Show
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,我无法形成一个"逻辑树",只能形成一个"逻辑列表".所以我需要一个类似Tree
但没有左右"分支" 的数据结构.
从鸟的角度来看,我的问题是:Haskell 中是否有通用的as-is
数据序列化机制?
问题的根源确实不在 Haskell 中。有一次,我尝试序列化一个 Python 字典,其中对象的哈希函数非常繁重。我发现在python中,默认的字典序列化并没有保存字典的内部结构,而只是转储了一个键值对列表。结果,反序列化的过程很耗时,也没有办法与之抗争。我确信在 Haskell 中有一种方法,因为在我看来,使用 BFS 或 DFS 自动将纯 Haskell 类型传输到字节流应该没有问题。令人惊讶,但事实并非如此。这里讨论了这个问题(引文如下)
目前,没有办法在不修改 HashMap 库本身的情况下使 HashMap 可序列化。如@mergeconflict 的回答所述,无法使用独立派生使 Data.HashMap 成为 Generic 的实例(用于谷物),因为 Data.HashMap 不导出其所有构造函数(这是 GHC 的要求)。因此,序列化 HashMap 的唯一解决方案似乎是使用 toList/fromList 接口。
我对Data.Trie
bytestring-trie package有同样的问题。为我的数据构建一个尝试非常耗时,我需要一种机制来序列化和反序列化这个轮胎。但是,看起来像以前的情况,我看不出如何制作Data.Trie
Generic 的实例(或者,我错了)?
所以问题是:
是否有某种通用机制可以将纯 Haskell 类型投影到字节字符串?如果不是,这是基本限制还是只是缺乏实现?
如果不是,修改bytestring-trie 包以使其成为 Generic 的实例并序列化的最轻松的方法是什么Data.Store
还有的实现HashMap
,在Haskell
,但我无法找到它的水货版本.有必要解决下面的问题.
说,我有两个哈希图HashMap a b
,我想将它与条件结合起来,现在我使用unionWith
函数,但问题是我的a
密钥的等价是非常长的过程(它是一个图形).所以我想并行执行它.我该怎么做?
假设,我有一个numpy
与向量n
的元素,所以我想编码序数在该载体作为二进制符号,所以得到的形状将是(n,m)
其中m
是log2(maxnumber)
例如:
x = numpy.array([32,5,67])
Run Code Online (Sandbox Code Playgroud)
因为我拥有的最大数量是67
,我需要numpy.ceil(numpy.log2(67)) == 7
位来编码这个向量,所以结果的形状将是(3,7)
array([[1, 0, 0, 0, 0, 1, 1],
[0, 0, 0, 0, 1, 0, 1],
[0, 1, 0, 0, 0, 0, 0]])
Run Code Online (Sandbox Code Playgroud)
问题出现是因为我没有快速的方法将二进制表示法从
函数移动numpy.binary_repr
到 numpy 数组。现在我必须迭代结果,并将每一位分别放置:
brepr = numpy.binary_repr(x[i],width=7)
j = 0
for bin in brepr:
X[i][j] = bin
j += 1
Run Code Online (Sandbox Code Playgroud)
这是非常耗时和愚蠢的方式,如何使其高效?
我使用Haskell和Functional Graph Library来表示图形.有两种比较图形的方法,直接,功能相等,或者在另一个函数上,我写道,isIsomorph.我想使用哈希映射来收集图表.为此,我必须为我的图形创建类Eq的实例.但是我需要两个哈希映射,第一个用于通过函数相等比较的图形,第二个用于通过函数进行比较的图形是Isomorph.
如果我做
type Fragment = Gr Atom Bond {-- Gr is a type constructor from the Functional Graph Library}
instance Eq (Gr Atom Bond) where
g == g1 = equal g g1
instance Eq Fragment where
g == g1 = isIsomorph g g1
Run Code Online (Sandbox Code Playgroud)
我有一个预期的错误
Duplicate instance declarations:
instance [overlap ok] Eq (Gr Atom Bond) -- Defined at HLab.hs:45:10
instance [overlap ok] Eq Fragment -- Defined at …
Run Code Online (Sandbox Code Playgroud) 我创建了一个类似的类型 Maybe
data Defined a = Is a | Undefined
我做了个Show
实话
instance Show a => Show (Defined a) where
show (Is a) = show a
show Undefined = "?"
Run Code Online (Sandbox Code Playgroud)
所以,我尝试实现该实例 Read
instance Read a => Read (Defined a) where
readsPrec _ s = case (take 1 s) of
"?" -> [(Undefined,tail s)]
otherwise -> map (\(a,b) -> (Is a,b)) $ readsPrec 0 s
Run Code Online (Sandbox Code Playgroud)
这是工作,但我不明白为什么.为什么这里没有无限循环:
otherwise -> map (\(a,b) -> (Is a,b)) $ readsPrec 0 s
Run Code Online (Sandbox Code Playgroud)
readsPrec 0 s …
我已经学习了Haskell一段时间了,但IO monad还是吓到了我.我有一个代码
main = do
putStrLn "First computation starts"
let firstResult = foo -- foo is a pure function
putStrLn "Second computation starts"
let secondResult = bar foo -- bar is too pure function
writeFile secondResult
Run Code Online (Sandbox Code Playgroud)
然后看看"First computation starts"
"Second computation starts"
程序会做什么.
我知道存在laisy计算,并且在writeFile
执行时真正开始计算.我试图增加严格性
main = do
putStrLn "First computation starts"
let !firstResult = foo -- foo is a pure function
putStrLn "Second computation starts"
let !secondResult = bar foo -- bar is too pure function
writeFile …
Run Code Online (Sandbox Code Playgroud) 我有一个程序,Haskell
从套接字获取所有输入并打印它.
main = withSocketsDo $ do
sock <- listenOn $ PortNumber 5002
netLoop sock
netLoop sock = do
(h,_,_) <- accept sock
hSetBuffering h NoBuffering
forkIO $ workLoop h
netLoop sock
workLoop :: Handle -> IO ()
workLoop h = do
str <- hGetContents h
putStr str
--do any work
Run Code Online (Sandbox Code Playgroud)
但问题是这个解决方案正在关闭套接字,但我想把计算结果写到同一个套接字上.但是,如果我尝试使用hGetLine
,而不是hGetContents
我面临着一些奇怪的行为.直到我按下Ctrl-C,我的程序才显示任何内容,然后我看到我的网络数据的第一行被发送.我建议这种行为与lasy执行有关,但为什么hGetContents按预期工作而hGetLine不行?