我刚刚花了大约一周的时间来搞清楚如何从C#执行C++代码作为我日常工作的一部分.我们花了很长时间才弄明白,但最终的解决方案相当简单.
现在我很好奇......从C#调用Haskell会有多难?(注意:这是从 C#调用Haskell ,而不是相反.所以主要的可执行文件是C#.)
如果它真的很难,我不会打扰.但如果它相当容易,我可能不得不玩它...
基本上,我们编写了一些C++代码.在Windows上,它被编译成一个DLL,在Linux上它被编译成一个共享对象(*.so).然后在C#端你做一个DllImport并写一些手动内存管理代码,如果你试图通过任何非常重要的事情.(例如,数组,字符串等)
我知道GHC应该支持在两个平台上构建共享库,但我不确定技术细节.导出内容的语法是什么,调用者是否必须先做一些特殊的事情来初始化DLL?
具体来说:假设存在一个函数foobar :: FilePath -> IO Int32.有人可以把一个小草图放在一起显示:
foobar.我不太担心C#端的实际语法; 我想我或多或少地对此感到困惑.
PS我做过简要介绍hs-dotnet,但这似乎是Windows特定的.(即,不适用于Mono,因此无法在Linux上运行.)
GHC的设计基于一种名为STG的东西,它代表"无骨架,无标签G机".
现在G-machine显然是"图形缩减机"的缩写,它定义了如何实现懒惰.未评估的thunk被存储为表达式树,并且执行该程序涉及将这些减少到正常形式.(树是非循环图,但Haskell的普遍递归意味着Haskell表达式形成一般图,因此图减少而不是树减少.)
不太清楚的是术语"无骨"和"无标记".
我认为 "无脊椎"指的是功能应用程序没有功能应用程序节点的"脊椎"这一事实.相反,您有一个对象,该对象命名所调用的函数并指向其所有参数.那是对的吗?
我认为"无标签"指的是构造函数节点没有用构造函数ID"标记",而是使用跳转指令解析case-expression.但现在我不确定这是否正确.相反,它似乎指的是节点没有用其评估状态标记的事实.谁能澄清这些解释中哪些(如果有的话)是正确的?
好的,所以我意识到我可能会在余生中后悔,但...... Djinn实际上是如何工作的?
文档说它使用的算法是"LJ的扩展",并指出了一篇关于LJT的长篇令人困惑的论文.就我所知,这是一个非常复杂的高度形式化规则系统,用于确定哪些逻辑陈述是真是假.但是,这甚至没有开始解释如何将类型签名转换为可执行表达式.据推测,所有复杂的形式推理都是以某种方式涉及的,但这种情况至关重要.
这有点像我在BASIC写一个Pascal解释器的时候.(不要笑!我只有十二岁......)我花了好几个小时试图解决它,最后我不得不放弃.我只是无法弄清楚你是如何从包含整个程序的巨型字符串中得到的,以及你可以与已知程序片段进行比较以确定实际操作的内容.
答案当然是你需要写一个叫做"解析器"的东西.一旦你理解了它是什么以及它做了什么,突然一切都变得明显.哦,编码它仍然不是一件容易的事,但这个想法很简单.你只需要编写实际的代码.如果我在十二岁时就知道解析器,那么也许我不会花两个小时只是盯着一个空白的屏幕.
我怀疑Djinn正在做的事情从根本上说很简单,但我遗漏了一些重要的细节,这些细节解释了所有这些复杂的逻辑体操如何与Haskell源代码相关...
我有一个使用多个线程的程序.据我了解,当线程0退出时,整个程序退出,无论其他线程可能仍在运行.
问题是,这些其他线程可能有文件打开.当然,这包含在异常处理代码中,以便在出现问题时干净地关闭文件.这也意味着如果我使用killThread(通过实现throwTo),该文件也应该在线程退出之前关闭.
我的问题是,如果我只是让线程0退出,而不试图阻止其他线程,那么各种文件句柄是否会被很好地关闭?是否刷新了任何缓冲输出?
简而言之,我可以退出,还是我需要先手动杀死线程?
构建GUI小部件类的层次结构几乎是面向对象编程的标准练习.你有一些抽象Widget类,有一个可以包含其他小部件的小部件的抽象子类,然后你有大量的支持文本显示的小部件的抽象类,支持作为输入焦点的小部件,具有布尔值的小部件状态,直到实际的具体类,如按钮,滑块,滚动条,复选框等.
我的问题是:在Haskell中执行此操作的最佳方法是什么?
有许多因素使构建Haskell GUI变得困难,但不是我的问题的一部分.在Haskell中进行交互式I/O有点棘手.实现GUI几乎总是意味着将包装器写入极低级别的C或C++库.编写这样的包装器的人倾向于逐字复制现有的API(可能是任何知道包装库的人都会有宾至如归的感觉).这些问题目前我不感兴趣.我真的很感兴趣的是如何最好地模拟Haskell中的子类型多态.
我们假设的GUI库需要什么样的属性?好吧,我们希望可以随时添加新的窗口小部件类型.(换句话说,一组封闭的可能小部件并不好.)我们希望最大限度地减少代码重复.(有很多小部件类型!)理想情况下,我们希望能够在必要时规定一个特定的小部件类型,但也能够在需要时处理任何小部件类型的集合.
在任何自尊的OO语言中,上述所有内容当然都是微不足道的.但是在Haskell中执行此操作的最佳方法是什么?我可以想到几种方法,但我不确定哪种方法会"最好".
我正在尝试做一些hoopy类型级编程,它只是不起作用.我正在试图弄清楚为什么GHC完全无法推断出我想要的类型签名.
有没有办法让GHC 告诉我它在做什么?
我尝试过-ddump-tc,只打印出最终的签名类型.(是的,他们错了.谢谢,我已经知道了.)
我也尝试过-ddump-tc-trace,它丢弃了大约70KB无法理解的乱码.(特别是,我看不到任何地方提到的任何用户编写的标识符.)
我的代码非常接近工作,但不知何故,一个额外的类型变量不断出现.出于某种原因,GHC无法看到这个变量应该完全确定.实际上,如果我手动编写五英里类型的签名,GHC很乐意接受它.所以我显然只是在某个地方错过了一个约束...... 但是在哪里?!?> _ <
当我第一次学习Haskell时,我很快就开始喜欢参数多态.这是一个令人愉快的简单想法,工作得非常好.整个"如果它编译它通常工作正常"的事情主要是由于参数多态,恕我直言.
但是前几天,我发生了一件事.我可以写成foo多态函数.但是当bar调用时foo,它将使用一组特定的参数类型来完成.或者,如果bar它本身是多态的,那么它的调用者将分配确定的类型.通过归纳,似乎如果您要采用任何有效的Haskell程序并分析整个代码库,您可以静态地确定整个程序中每个事物的类型.
从某种意义上说,这有点像C++模板.没有运行时多态,只有编译时多态.Haskell编译器可以选择为每个调用每个多态函数的类型生成单独的机器代码.大多数Haskell编译器没有,但如果你愿意,你可以实现一个.
只有当你开始添加Haskell扩展(ExistentialQuantification显而易见的是)时,你才开始获得真正的运行时多态性,你可以在其中获得无法静态计算类型的值.
哦,是的,我的问题?
以上陈述是否真的正确?
这个属性有广泛使用的名称吗?
当我第一次学习Haskell时,Haskell '98是官方发布的语言规范.今天,该规范是Haskell 2010.(我必须承认,我真的很难记住差异究竟是什么.)
现在Haskell已经存在了很长时间.(好吧,在计算方面,这是一段很长的时间.)所以我想知道的是......在Haskell的历史中,语言是否有任何重大的设计变化?或者所有变化都相对较小?有什么地方我可以找到这些列表,而不是坐下来阅读每个版本的Haskell报告试图发现差异?
它在标题中说的是什么.如果我写一个类型签名,是否可以通过算法生成具有该类型签名的表达式?
似乎有可能做到这一点.我们已经知道,如果类型是库函数类型签名的特例,Hoogle可以通过算法找到该函数.另一方面,与一般表达式相关的许多简单问题实际上是无法解决的(例如,不可能知道两个函数是否做同样的事情),因此这是其中之一几乎难以置信.
一次问几个问题可能是不好的形式,但我想知道:
可以吗?
如果是这样,怎么样?
如果没有,是否有可能的限制情况?
两个不同的表达式很可能具有相同的类型签名.你能算出所有这些吗?甚至其中一些?
有没有人有工作代码,这是真的吗?
我知道monad是什么.我想我已经正确地把我的想法包围在一个comonad是什么.(或者说,什么人是看起来非常简单,最棘手的部分是理解什么是有用的这个...)
我的问题是:有什么东西可以成为monad 和 comonad吗?
我预见到两个可能的答案:
那么,这是什么?
haskell ×10
types ×4
bytecode ×1
c# ×1
compilation ×1
debugging ×1
ffi ×1
ghc ×1
logic ×1
polymorphism ×1