什么是一些使用Haskell的开源程序,可以被认为是优质的现代Haskell?代码库越大越好.
我想从他们的源代码中学习.我觉得我已经超越了从小代码示例中学到的东西,这些代码通常是深奥的,小世界的.我想看看代码是如何构造的,当你有很多事情发生时,monad如何交互(日志记录,I/O,配置等).
这是我想做的事情:
1. `link <http://www.google.com>`__
2. `link <http://www.yahoo.com>`__
Run Code Online (Sandbox Code Playgroud)
获得:
<ol>
<li><a href="http://www.google.com">link</a></li>
<li><a href="http://www.yahoo.com">link</a></li>
</ol>
Run Code Online (Sandbox Code Playgroud)
上下文是一个出版物列表,我希望它们在最后都有一个标记为"DOI"的链接.
但是,这似乎失败了:
<string>:3: (WARNING/2) Duplicate explicit target name: "doi".
Run Code Online (Sandbox Code Playgroud)
确切的错误似乎取决于我使用的docutils版本,但它们都失败了.
有没有办法在重组文本中生成具有相同文本的多个链接?
我已经看到了showS对构建字符串的技巧的引用(例如,在本讨论中),但我从未见过它的良好描述.
什么是showS技巧?
从概念上讲,执行输出的计算似乎与仅执行输入的计算非常不同.从某种意义上说,后者更为纯粹.
举个例子,我希望有一种方法可以将我的程序中仅输入的部分与可能实际写出的部分分开.
那么,为什么只有Monad没有输入?
任何原因导致I monad(以及可以合并到IO Monad中的O Monad)的任何原因?
编辑:我主要是指输入为阅读文件,而不是与用户交互.这也是我的用例,我可以假设输入文件在程序执行期间不会改变(否则,可以获得未定义的行为).
我有一个应用程序,内部循环的一部分基本上是:
double sum = 0;
for (int i = 0; i != N; ++i, ++data, ++x) sum += *data * x;
Run Code Online (Sandbox Code Playgroud)
如果x是unsigned int,那么代码需要3倍于int!
这是一个更大的代码库的一部分,但我把它归结为要点:
#include <iostream>
#include <cstdlib>
#include <vector>
#include <time.h>
typedef unsigned char uint8;
template<typename T>
double moments(const uint8* data, int N, T wrap) {
T pos = 0;
double sum = 0.;
for (int i = 0; i != N; ++i, ++data) {
sum += *data * pos;
++pos;
if (pos == wrap) pos = 0;
} …Run Code Online (Sandbox Code Playgroud) 我的背景是生物信息学,特别是新一代测序,但问题是通用的; 所以我将使用日志文件作为示例.
该文件非常大(千兆字节大,压缩,因此它不适合内存),但很容易解析(每行都是一个条目),所以我们可以轻松地写出如下内容:
parse :: Lazy.ByteString -> [LogEntry]
Run Code Online (Sandbox Code Playgroud)
现在,我有很多我想从日志文件中计算的统计信息.编写单独的函数是最简单的,例如:
totalEntries = length
nrBots = sum . map fromEnum . map isBotEntry
averageTimeOfDay = histogram . map extractHour
Run Code Online (Sandbox Code Playgroud)
所有这些都是这种形式foldl' k z . map f.
问题是,如果我尝试以最自然的方式使用它们,比如
main = do
input <- Lazy.readFile "input.txt"
let logEntries = parse input
totalEntries' = totalEntries logEntries
nrBots' = nrBots logEntries
avgTOD = averageTimeOfDay logEntries
print totalEntries'
print nrBots'
print avgTOD
Run Code Online (Sandbox Code Playgroud)
这会将整个列表分配到内存中,这不是我想要的.我希望折叠同步完成,以便可以对垃圾收集进行垃圾收集.如果我只计算一个统计量,就会发生这种情况.
我可以写一个这样做的大函数,但它是不可组合的代码.
或者,这就是我一直在做的,我分别运行每个传递,但每次重新加载和解压缩文件.
使用Control.Applicative对Parsec非常有用,但是你需要始终隐藏<|>和类似的对象,因为它们与Parsec自己的冲突:
import Control.Applicative hiding ((<|>), many, optional)
import Text.Parsec.Combinator
import Text.Parsec
Run Code Online (Sandbox Code Playgroud)
或者,正如Antal SZ指出的那样,您可以隐藏Parsec版本.但是,据我所知,这似乎是一个不必要的限制.
为什么parsec不是简单地从Applicative实现这些运算符?
在Haskell中,我经常用$表示表达式.我发现它非常自然和可读,但我有时读到它是不好的形式,不明白为什么它应该是.
举个例子,假设我希望实现一个总结Nums 列表的函数.在编写代码的过程中,我希望通过以下方式对其进行调试Debug.Trace:
module T where
import Debug.Trace
dosum :: (Num a) => [a] -> a
dosum xs = dosum' 0 xs
where
dosum' n [] = n
dosum' n (x:xs) = trace (show n) $ dosum' (n+x) xs
Run Code Online (Sandbox Code Playgroud)
问题是这不会编译:
Could not deduce (Show a) arising from a use of dosum'
from the context (Num a)
Run Code Online (Sandbox Code Playgroud)
我可以添加(Show a)到dosum,然后删除它,当我完成调试(在现实生活中,我会希望有这样一种类型,不一定在Show,但我会用整数调试).如果涉及一些函数并且我不断添加删除Show a语句,这会很麻烦.
我想要一个功能 unsafeShow
unsafeShow :: a -> String
Run Code Online (Sandbox Code Playgroud)
如果a是 …
我关于计算机视觉的讲义提到,如果我们知道聚类的标准偏差,那么k均值聚类算法的性能可以提高.怎么会这样?
我的想法是,我们可以使用标准差来首先通过基于直方图的分割得出更好的初始估计.你怎么看?谢谢你的帮助!
haskell ×7
coding-style ×2
performance ×2
algorithm ×1
bigdata ×1
c ×1
c++ ×1
debugging ×1
io ×1
k-means ×1
monads ×1
open-source ×1
parsec ×1
python ×1
x86 ×1