我今天早些时候看到了荒谬功能的逆向,虽然我很清楚,任何可能的实现drusba :: a -> Void都永远不会终止(毕竟,它是不可能构建的Void),但我不明白为什么同样不是这样absurd :: Void -> a.考虑GHC的实施:
newtype Void = Void Void
absurd :: Void -> a
absurd a = a `seq` spin a where
spin (Void b) = spin b
Run Code Online (Sandbox Code Playgroud)
spin在我看来,它无休止地解开了无限系列的Void新型包装器,即使你能找到Void传递它也永远不会返回.无法区分的实现类似于:
absurd :: Void -> a
absurd a = a `seq` undefined
Run Code Online (Sandbox Code Playgroud)
鉴于此,为什么我们说这absurd是一个值得生活在Data.Void中的适当函数,但是
drusba :: a -> Void
drusba = undefined
Run Code Online (Sandbox Code Playgroud)
是一个不可能定义的函数?它是否像以下那样?
absurd是一个总函数,为其(空)域中的任何输入提供非底部结果,而drusba为部分,给出其域中某些(实际上所有)输入的最低结果.
float __stdcall (*pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280;
Run Code Online (Sandbox Code Playgroud)
如何用调用约定声明一个函数指针?上面给了我一个错误.
我想编写一个with-test-tags包含大量表单的Clojure 宏,并在每个deftest表单的名称中添加一些元数据- 具体来说,在:tags键中添加一些东西,这样我就可以使用工具来运行具体的测试标签.
一个明显的实现with-test-tags是递归地遍历整个身体,deftest在我找到它时修改每个表单.但是我最近一直在阅读Let Over Lambda,他提出了一个很好的观点:不要自己编写代码,只需将代码包装好,macrolet然后让编译器为你完成.就像是:
(defmacro with-test-tags [tags & body]
`(macrolet [(~'deftest [name# & more#]
`(~'~'deftest ~(vary-meta name# update-in [:tags] (fnil into []) ~tags)
~@more#))]
(do ~@body)))
(with-test-tags [:a :b]
(deftest x (...do tests...)))
Run Code Online (Sandbox Code Playgroud)
但是,这有一个明显的问题,即deftest宏继续递归地递增.我可以将它扩展为clojure.test/deftest相反,从而避免任何进一步的递归扩展,但是我无法有效地嵌套with-test-tags标记子组测试的实例.
在这一点上,特别是对于简单的事情deftest,它看起来像走自己的代码会更简单.但我想知道是否有人知道编写宏的技术,它会"略微修改"某些子表达式,而不会永远递归.
对于好奇:我考虑了一些其他的方法,例如我有一个编译时binding可变的var,我设置为上下代码,并在我最终看到a时使用该var deftest,但由于每个宏只返回一个扩展它的绑定将不适用于下一次调用macroexpand.
我刚刚做了postwalk实现,虽然它工作但它不尊重特殊形式,例如quote- 它也扩展到那些内部.
(defmacro with-test-tags [tags & body]
(cons `do
(postwalk (fn [form]
(if …Run Code Online (Sandbox Code Playgroud) 我最近一直在寻找延续,我对正确的术语感到困惑.Gabriel Gonzalez 在这里说:
Haskell延续具有以下类型:
Run Code Online (Sandbox Code Playgroud)newtype Cont r a = Cont { runCont :: (a -> r) -> r }
即整个(a -> r) -> r事情是延续(没有包装)
在维基百科的文章,似乎说支持这个想法
延续是计算机程序的控制状态的抽象表示.
但是,这里作者说
Continuations是表示"要执行的剩余计算"的函数.
但这只是(a->r)该Cont类型的一部分.这与Eugene Ching 在这里所说的一致:
计算(函数),需要一个连续函数才能完全评估.
我们将会看到很多这样的功能,因此,我们会给它一个更直观的名称.我们叫他们等待功能.
我已经看到了另一个教程(Brian Beckman和Erik Meijer),他们调用了整个事物(等待函数)observable以及它完成观察者所需的函数.
(a->r)->r东西或只是(a->r)东西(没有包装)?我正在为其他人的Stack Overflow问题玩一个简单的函数,并编写了表达式:
f a x ++ f a y
Run Code Online (Sandbox Code Playgroud)
显然这是在现实生活中编写该表达式的最佳方式,因为无论如何我在范围内都有所有这些变量,但是我看到了重复f a,并且认为"嘿,也许你可以用函数的Applicative实例删除它".我结束了:
liftA2 (++) (flip f x) (flip f y) a
Run Code Online (Sandbox Code Playgroud)
这太可怕了.有没有更好的方法来删除这种重复?显然我也可以通过绑定f a到某个东西来删除重复where子句中的,但这是一个使用内置函数的练习.
我的一个朋友最近得到了这个面试问题,这在我们看来是可以解决的,但不是在面试官认为应该可能的渐近时间范围内.这是问题所在:
你有一个
N整数数组xs,排序但可能不同.您的目标是找到四个数组索引(1)(a,b,c,d),以便以下两个属性成立:Run Code Online (Sandbox Code Playgroud)xs[a] + xs[b] + xs[c] = xs[d] a < b < c < d目标是在O(N 2)时间内完成此操作.
首先,O(N 3 log(N))解决方案是显而易见的:对于每个(a,b,c)有序三元组,使用二进制搜索来查看是否d可以找到合适的.现在,如何做得更好?
面试官的一个有趣建议是将第一个条件重写为:
xs[a] + xs[b] = xs[d] - xs[c]
Run Code Online (Sandbox Code Playgroud)
在此之后还不清楚该怎么做,但也许我们可以选择一些枢轴值P,并搜索一(a,b)对加起来为P,一(d,c)对减去它.对于给定的P,通过从数组的两端向内搜索,该搜索很容易在O(n)时间内完成.然而,在我看来,这个问题是N 2这样的值P,而不仅仅是N,所以我们实际上根本没有减小问题的大小:我们正在进行O(N)工作, O(N 2)次.
我们发现在其他地方在线讨论了一些相关的问题:在N 2时间内,在一个数组中找到添加到给定总和的3个数字是可解的,但要求总和提前修复; 适应相同的算法,但迭代每个可能的总和使我们一如既往地在N 3.
另一个相关的问题似乎是在数组中查找所有三元组,其总和小于或等于给定的总和,但我不确定这里有多少相关的东西:不等式而不是平等混合了很多东西,当然,目标是固定的而不是变化的.
那么,我们缺少什么?考虑到性能要求,问题毕竟是不可能的吗?还是有一个我们无法发现的聪明算法?
(1)实际上提出的问题是找到所有这样的(a,b,c,d)元组,并返回有多少元组的计数.但我认为即使在所需的时间限制内找到其中一个也很难.
我是Cojure的新手,但我读到在使用AOT编译时会为每个函数生成一个类.这是不是意味着很多消耗了perm-gen空间的类?这有什么问题吗?什么时候不使用AOT编译,但是动态生成字节码?
使用clojure函数,我可以定义:
(defn f [x & xs] (apply some-function x xs))
Run Code Online (Sandbox Code Playgroud)
我试图用协议做同样的事情,例如
(defprotocol foo
(bar [f])
(baz [f & gs]))
Run Code Online (Sandbox Code Playgroud)
这编译(至少在REPL中),但任何实现类型似乎都失败了(变量,baz)方法.官方不支持这个吗?我咨询过的消息来源是沉默的.
学习新语言的最佳方法是阅读结构良好且记录完备的项目,这些项目以正确的方式使用语言结构.
什么是最好的clojure回购阅读和从中学习?
为什么user对象仍具有Nothing用于createdAt和updatedAt?为什么这些字段没有被数据库分配?
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
User
email String
createdAt UTCTime Maybe default=CURRENT_TIME
updatedAt UTCTime Maybe default=CURRENT_TIME
deriving Show
|]
main = runSqlite ":memory:" $ do
runMigration migrateAll
userId <- insert $ User "saurabhnanda@gmail.com" Nothing Nothing
liftIO $ print userId
user <- get userId
case user of
Nothing -> liftIO $ putStrLn ("coulnt find userId=" ++ (show userId))
Just u -> liftIO $ putStrLn ("user=" ++ (show user))
Run Code Online (Sandbox Code Playgroud)
输出:
UserKey {unUserKey …Run Code Online (Sandbox Code Playgroud)