我想知道是否有某种方法可以让Haskell在JVM上运行(编译或解释)?
在Sourceforge上存在JHaskell但这个似乎是空的并且已经死了.
GHC使用LLVM作为编译器后端.将LLVM编译为Java字节码是一个好主意还是可能的?或者也许使用不同的编译器后端?
Scala和Frege都是针对JVM的类型化函数语言.
弗雷格更接近哈斯克尔,斯卡拉有更独立的历史.
但是如果我们不看语法差异,两者之间允许的编程技术,风格,概念有什么不同?
Haskell 2010语言报告在第20.10.1.1节中指出:
deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
事实上,GHC库中的实现将允许
deleteBy :: (b -> a -> Bool) -> b -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)
但实际上使用注释将类型限制为前者.
因此,人们不能说,例如:
foo = deleteBy fsteq 42 [(43, "foo"), (44, "bar"), (42, "baz")] where
fsteq a (b,_) = a == b
Run Code Online (Sandbox Code Playgroud)
因为Int不一样(Int, String).
这有什么好的理由吗?
我问的原因是,如果没有充分的理由,我会deleteBy在我正在做的Data.List 的Frege端口中包含更通用的类型.但也许我忽略了什么?
编辑:正如@hammar所指出的,这也适用于其他xxx By函数.
是否有任何Frege相当于Haskell,getLine并read从标准库中的控制台解析输入?
目前我这样做:
import frege.IO
getLine :: IO String
getLine = do
isin <- stdin
isrin <- IO.InputStreamReader.new isin
brin <- IO.BufferedReader.fromISR isrin
line <- brin.readLine
return $ fromExceptionMaybe line
fromExceptionMaybe :: Exception (Maybe a) -> a
fromExceptionMaybe (Right (Just r)) = r
fromExceptionMaybe (Right _) = error "Parse error on input"
fromExceptionMaybe (Left l) = error l.getMessage
pure native parseInt java.lang.Integer.parseInt :: String -> Int
main _ = do
line <- getLine
println $ parseInt line …Run Code Online (Sandbox Code Playgroud) 尾部调用是否在Frege中进行了优化.我知道在Java和编译为JVM字节码的语言中都没有TCO,如Clojure和Scala.弗雷格怎么样?
作为练习,我将这些Scala和Java的Akka示例移植到了Frege.虽然它工作正常,但它比Scala(540ms)对应的运行速度慢(11s).
module mmhelloworld.akkatutorialfregecore.Pi where
import mmhelloworld.akkatutorialfregecore.Akka
data PiMessage = Calculate |
Work {start :: Int, nrOfElements :: Int} |
Result {value :: Double} |
PiApproximation {pi :: Double, duration :: Duration}
data Worker = private Worker where
calculatePiFor :: Int -> Int -> Double
calculatePiFor !start !nrOfElements = loop start nrOfElements 0.0 f where
loop !curr !n !acc f = if n == 0 then acc
else loop (curr + 1) (n - 1) (f acc …Run Code Online (Sandbox Code Playgroud) 似乎Frege关于类型类的想法与Haskell有很大不同.特别是:
语法似乎不同,没有明显的原因.
函数类型不能包含类实例.(似乎是一个相当奇怪的规则......)
语言规范说明了在子类实例声明中实现超类.(但如果你有钻石继承,那就不行了......这不会是一个错误,但它不能保证以某种方式工作?)
弗雷格对实例的看法不那么挑剔.(允许输入别名,类型变量不需要是不同的,等等)
方法可以声明为native,虽然还不完全清楚这是什么意思.
您似乎可以编写type.method访问方法.同样,没有迹象表明这意味着什么或为什么它有用.
子类声明可以为超类方法提供默认实现.(?)
简而言之,如果知道这些东西的人可以写出这些东西如何工作的解释将是有用的.它在语言规范中列出,但描述有点简洁.
(关于语法:我认为Haskell的实例语法更合乎逻辑."如果X是Y和Z的实例,那么它也是以下列方式的Q实例......"Haskell的类语法总是看起来有点奇怪对我来说.如果X实现Eq,这并不意味着它实现Ord,它暗示它可以实现,Ord如果它想要.我不知道什么是更好的符号将...)
Per Ingo的回答:
例如,假设Foo是一个超类Bar.假设每类有三种方法(foo1,foo2,foo3,bar1,bar2,bar3),并Bar提供了一个默认的实现foo1.这应该意味着
instance Bar FB where foo2 = ... foo3 = ... bar1 = ... bar2 = ... bar3 = ...
应该管用.但是这会有用吗:
instance Foo FB where foo2 = ... foo3 = ... instance Bar …
似乎弗雷格可以评估
1/2
Run Code Online (Sandbox Code Playgroud)
返回Double值0.5.
文字1属于类型Int.它似乎被提升为Double,这是类中的一种类型Real,因此知道/运算符.这是怎么发生的?它是否正在使用Haskell方法静默替换文字1 fromInt 1或正在进行其他事情?如何Double选择在Real这里使用的实例?是否有像Haskell一样的"默认"实例类型列表?
嗨我和弗雷格一直在玩一点,我在一些例子中注意到package并且module可以互换使用:
package MyModuleOne where
Run Code Online (Sandbox Code Playgroud)
而有时:
module MyModuleTwo where
Run Code Online (Sandbox Code Playgroud)
从一个或另一个导入时,我看不到我的程序行为有任何差异.在使用package或module关键字时,我应该记住一些事项吗?