说我有一个列表,如:
[Nothing, Just 1, Nothing, Just 2]
Run Code Online (Sandbox Code Playgroud)
我想得到第一个Just(非错误)值; 在这种情况下,它是Just 1.我唯一能想到的是:
firstJust xs = case filter isJust xs of
[] -> Nothing
Just x -> Just x
Run Code Online (Sandbox Code Playgroud)
有没有更好的/ monad-generic方法来做到这一点?
我正在尝试提高客户端从我的 Compojure 网络服务器获取页面的性能。我们使用 提供了一堆静态文件(JS、CSS)(compojure.route/resources "/"),它在文件系统上查找文件,将它们转换为 URL,然后将它们作为流提供给 Ring。通过转换为流,它似乎丢失了所有文件元数据,例如 mod 时间。
我可以包装静态资源处理程序并添加一个ExpiresorCache-Control: max-age标头,但这会阻止客户端发送任何请求。很有用,但这些文件有时会更改(当我们发布版本时)。
理想情况下,我希望客户端信任其自己的缓存版本,例如一个小时,并If-Modified-Since在该小时过去后使用标头发出请求。然后我们可以返回304 Not Modified,客户端避免下载几百公斤的 javascript。
看起来我可以Last-Modified在提供响应时设置标头,这会导致客户端使用If-Modified-Since标头限定后续请求。很好,除了我必须重写大部分代码compojure.route/resources才能添加Last-Modified- 不难,但很乏味 - 并发明更多代码来识别和响应If-Modified-Since标头。不是一项艰巨的任务,但也不是一项简单的任务。
这是否已经存在于某处?我找不到它,但它似乎是一项足够常见且足够大的任务,以至于现在有人会为它编写一个库。
我想实现transient并persistent!在我的Clojure deftype中.据我所知,这意味着有另一个deftype,TransientMyThing,实现必要的方法.好的到目前为止,但是这两个类需要彼此了解才能返回彼此的实例.
我想我可以通过前向声明Clojure函数make-transient和make-persistent,然后定义deftype(通过引用该函数),然后使用现有类型实现函数来实现,但对我来说似乎很糟糕.有更好的选择吗?
编辑:这有效,但它仍然很严重.
如果这是一个简单的问题,我深表歉意。我已经指定了一个输入文件,该文件位于代码源文件的同一目录中。
isprime :: Int -> [Int] -> Bool
isprime ...
main = do
handle <- openFile "primes-to-100k.txt" ReadMode
contents <- hGetContents handle
i <- getLine
print $ isprime (read i::Int) $ map (\x->read x::Int) $ lines contents
hClose handle
Run Code Online (Sandbox Code Playgroud)
当我在 shell 中使用“runhaskell Q111.hs”时,代码运行良好,但是当我使用“ghc --make Q111.hs”编译并运行时,出现错误消息
Q111: primes-to-100k.txt: openFile: 不存在(没有这样的文件或目录) 注销
关键是代码在 ghci 和 runhaskell 上运行良好,但可执行文件找不到输入 txt。
我是否必须使用某种方式向编译器提供输入 txt?
我的问题是关于 clojure 原子中的嵌套映射/键以及如何同时更新它们。在我的情况下,我在另一个地图中有一个嵌套地图,它是一个持有小游戏原子的状态。
这是我的原子:
(def state (atom {:mousePos {:x 0 :y 0}
:playArea {:width 10000 :height 10000}
:player {:zoomOut 7.5
:cells [{:center {:x 1234 :y 5678}
:radius 17.84124116
:area 1000}]
:gravityCenter {:x 1234 :y 5678}
:gravityRadius 17.84124116}}))
Run Code Online (Sandbox Code Playgroud)
在这个原子中,我想同时更新 mousePos x 和 y 值以确保它们的一致性/并发性。
目前我正在做:
(swap! state assoc-in [:mousePos :x] mouseX)
(swap! state assoc-in [:mousePos :y] mouseY)
Run Code Online (Sandbox Code Playgroud)
但那些是两个交换!理论上如果线程之间切换我可能会遇到问题,对于另一个线程中的以下操作,我将使用当前的 x 但鼠标的旧 y 位置我不想要那个。
所以我希望做这样的事情:
(swap! state assoc-in [:mousePos :x] mouseX
[:mousePos :y] mouseY)
Run Code Online (Sandbox Code Playgroud)
女巫当然不会工作,所以我尝试编写自己的 assoc-in-mult 函数,这就是我不成功的地方。
我最近定义了一个类型,我可能无法计算其字段:
data Foo = Foo {x, y :: Int, others :: NonEmpty Int}
data Input
computeX, computeY :: Input -> Maybe Int
computeOthers :: Input -> Maybe (NonEmpty Int)
Run Code Online (Sandbox Code Playgroud)
现在,我可能做的一件明显的事情就是使用liftA3:
foo :: Input -> Maybe Foo
foo i = liftA3 Foo (computeX i) (computeY i) (computeOthers i)
Run Code Online (Sandbox Code Playgroud)
Foo这很好用,但我认为推广到hold Maybes,然后将一种类型转换为另一种类型可能会很有趣Foo。在一些类似的情况下,我可以给该Foo类型一个类型参数并派生 Traversable。然后在创建之后Foo (Maybe Int),我可以使用 立即反转整个事情sequenceA :: Foo (Maybe Int) -> Maybe (Foo Int)。但这在这里不起作用,因为我的函数没有给我一个NonEmpty (Maybe Int),它给了我一个Maybe (NonEmpty Int) …
我一直在处理我写的服务器的问题.它在Clojure中,但我认为这并不重要,我们可以假装它是用Java编写的.无论如何,它工作正常,在一个小时的时间,但进入配合它的表现非常糟糕:所有的活动停止,为大约十五秒钟,然后它正常工作了几秒钟,然后停止十五秒...等(通常)大约十分钟左右,然后恢复正常行为.
我用YourKit做了很多分析,我排除了一些看似合理的嫌疑人:
这不是垃圾收集问题:我正在运行它-XX:+UseConcMarkSweepGC,并且我已经验证了服务器在次要和主要集合期间继续运行正常,因为这个垃圾收集器的并发性质.当我们耗尽总内存或其他东西时,我们并没有挣扎:当前堆大小远低于其最大值.
我不认为这是一个锁定/同步问题,但我不是100%肯定.YourKit分析器有时会显示等待的线程,例如通过锁定来竞争System.out以生成日志消息,但是当没有任何事情要做时,唯一的长等待是线程池中的工作线程.当然,YourKit说它从来没有发现任何死锁.
这不是因为连接了探查器而引起的,因为即使我启动服务器然后在不附加探查器的情况下单独使用它仍然会发生.
这不是系统占用所有CPU时间的其他过程:top我的java进程显示CPU使用率为100%,其他所有内容基本上为0%.
我最大的问题是,在这些奇怪的问题中我无法看到服务器正在做什么,因为探查器停止接收样本.这是CPU使用率图表的图表:

图的左侧是正常操作,在此期间我们每隔一秒左右获得一次探查器样本.右侧是"破碎的",并且非常尖刻,因为探测器每10秒左右才会获取样品.在它确实获得的样本中,服务器似乎正在做其通常的业务:响应请求等等; 和日志确认它是做正常的东西,但只能在次探查具有样本:在图表上,为此,探查有没有样品向上倾斜"直线",服务器都无所事事.
那么,这个图表对任何人来说都很熟悉吗?你以前遇到过这个问题并修好了吗?或者你能指出一个工具的方向,可以找出我的服务器在YourKit不能做的时候做了什么吗?如果它很重要,服务器机器正在运行Ubuntu 10.04,和
$ java -version
java version "1.6.0_22"
OpenJDK Runtime Environment (IcedTea6 1.10.10) (rhel-1.28.1.10.10.el5_8-x86_64)
OpenJDK 64-Bit Server VM (build 20.0-b11, mixed mode)
Run Code Online (Sandbox Code Playgroud) 我有一个seq, (def coll '([:a 20] [:b 30] [:c 50] [:d 90]))
我想迭代seq,并只修改与谓词匹配的第一个元素.
谓词 (def pred (fn [[a b]] (> b 30)))
(f pred (fn [[a b]] [a (+ b 2)]) coll) => ([:a 20] [:b 30] [:c 52] [:d 90])
f是我想要的fn,它取一个pred,一个fn应用于匹配pred的第一个elem.所有其余的元素都没有修改并在seq中返回.
做上述的惯用方法是什么?
我注意到我的一个 SQL 查询比我预期的要慢得多,结果查询计划程序提出了一个对我来说似乎很糟糕的计划。我的查询如下所示:
select A.style, count(B.x is null) as missing, count(*) as total
from A left join B using (id, type)
where A.country_code in ('US', 'DE', 'ES')
group by A.country_code, A.style
order by A.country_code, total
Run Code Online (Sandbox Code Playgroud)
B 有一个 (type, id) 索引,A 有一个 (country_code, style) 索引。A 比 B 小得多:A 中有 250K 行,B 中有 100M。
所以,我希望查询计划看起来像:
country_code(type, id)索引查找匹配行(如果有)country_code和分组事物style但是查询规划器决定执行此操作的最佳方法是对 B 进行顺序扫描,然后对 A 进行右连接。我无法理解为什么会这样;有没有人有想法?这是它生成的实际查询计划:
Sort (cost=14283513.27..14283513.70 rows=171 width=595)
Sort Key: a.country_code, …Run Code Online (Sandbox Code Playgroud) 我听说每个拉链都是一个共元,而我认为每个与其自身组成的拉链仍然是一个拉链,因此它是一个共元。所以我决定创建一个。
\n我有以下拉链列表:
\n{-# LANGUAGE DeriveFunctor #-}\n{-# LANGUAGE InstanceSigs #-}\nmodule ListZipper where\nimport Control.Comonad\nimport Data.List (unfoldr)\nimport Test.QuickCheck (Arbitrary (arbitrary))\n\ndata ListZipper a = ZList {previous :: [a], currentL :: a, next :: [a]} deriving (Functor, Eq)\n\ngoLeft, goRight :: ListZipper a -> Maybe (ListZipper a)\ngoLeft (ZList (p:ps) cur ns) = Just $ ZList ps p (cur : ns)\ngoLeft _ = Nothing\ngoRight (ZList ps cur (n:ns)) = Just $ ZList (cur : ps) n ns\ngoRight _ = Nothing\n\nfork :: b -> (b, b)\nfork …Run Code Online (Sandbox Code Playgroud) clojure ×5
haskell ×4
performance ×2
comonad ×1
compojure ×1
composition ×1
deftype ×1
functor ×1
http ×1
http-headers ×1
indexing ×1
instance ×1
java ×1
maybe ×1
monads ×1
postgresql ×1
profiling ×1
sql ×1
state ×1
yourkit ×1