我有两个发电机,gen_n&gen_arr:
gen_n :: Gen Int
gen_n = suchThat arbitrary (\i -> i >= 0 && i <= 10)
gen_elem :: Gen Int
gen_elem = suchThat arbitrary (\i -> i >= 0 && i <= 100)
gen_arr :: Gen [Int]
gen_arr = listOf gen_elem
Run Code Online (Sandbox Code Playgroud)
我如何将这两者结合成一个Gen (Int, [Int])?
combine_two_gens :: Gen a -> Gen b -> Gen (a, b)
Run Code Online (Sandbox Code Playgroud) 嗨我和弗雷格一直在玩一点,我在一些例子中注意到package并且module可以互换使用:
package MyModuleOne where
Run Code Online (Sandbox Code Playgroud)
而有时:
module MyModuleTwo where
Run Code Online (Sandbox Code Playgroud)
从一个或另一个导入时,我看不到我的程序行为有任何差异.在使用package或module关键字时,我应该记住一些事项吗?
我想了解Frege List的工作原理以及如何从Java中使用它.当我下载Frege编译器代码时,我发现很难理解Frege代码中的Frege List是什么.
做一些测试我发现Frege List是TListJava中类的一个实例,它带有一个特殊的方法,叫做_Cons()返回一个DCons对象.DCons正如所料,是一对,其中该对的第一个元素对应于列表的头部,而第二个元素是尾部,因此是另一个TList.在_Cons()空列表上调用时,返回值为null.因此,要在Frege上实现Java迭代器TList,可以编写:
public class TListIterator implements Iterator<Object> {
DCons elem;
public TListIterator(TList list) {
this.elem = list._Cons();
}
@Override
public boolean hasNext() {
return this.elem != null;
}
@Override
public Object next() {
final Object head = Delayed.<Object>forced( this.elem.mem1 );
this.elem = this.elem.mem2.<TList>forced()._Cons();
return head;
}
@Override
public void remove() {
throw new RuntimeException( "Remove is not implemented" );
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
你将如何调整这个简单的递归示例,以便发生尾调用优化(而不是a StackOverflowError)?
count 0 = 0
count n = succ (count (pred n))
count 100000
Run Code Online (Sandbox Code Playgroud) 根据Hoogle的说法,<=<(Kleisli monad组合,或"左鱼")和=<<(反向monad bind)的固定性是infixr 1.如果我正确地看着它们,就像说的那样
print <=< return =<< return "foo"
Run Code Online (Sandbox Code Playgroud)
应该是无效的,因为它等同于同样无效的
print <=< (return =<< return "foo")
Run Code Online (Sandbox Code Playgroud)
但出于某种原因,尽管第一个表达似乎在Haskell中是无效的,正如预期的那样,弗雷格似乎没有抱怨,并<=<在之前进行评估=<<.
当我在pointfree.io上弄乱如何弄清楚如何制作类似的东西时,我发现了这一点
foo >>= (bar <=< baz)
Run Code Online (Sandbox Code Playgroud)
没有点,它给了我
bar <=< baz =<< foo
Run Code Online (Sandbox Code Playgroud)
考虑到固定性,这看起来不太对劲.
在Frege中,我想将 String 转换为 Int,但也需要处理无法解析的字符串。
所以我想我正在寻找类似readMaybe函数的东西。我在哪里可以找到这个?或者我如何使用 JavaparseInt并捕获 Frege 中的异常?
在Haskell:
ghci> :type null
null :: [a] -> Bool
Run Code Online (Sandbox Code Playgroud)
在弗雷格:
frege> :type null
Empty ? => ? ? -> Bool
Run Code Online (Sandbox Code Playgroud)
我如何解释这个答案,为什么会有区别?
(来自现实世界的haskell的例子,改编自现实世界的frege git repo)
假设你提示用户输入用的组合putStr和getLine:
main = do
putStrLn "A line with line termination" -- printed correctly
putStr "A line without line termination, e.g. to prompt for input: " -- NOT printed
line <- getLine
putStrLn ("You entered: " ++ line)
Run Code Online (Sandbox Code Playgroud)
与Haskell相比,Frege不打印第二行(使用putStr而不是putStrLn).这种缺失冲洗的行为是否意图?
如果Frege偏离Haskell行为,我会认为它模仿Java的行为.概念上类似的例子:
public static void main(String[] args) {
System.out.println("A line with line termination");
System.out.print("A line without line termination, e.g. to prompt for input: ");
String line = new java.util.Scanner(System.in).nextLine();
System.out.println("You entered: " + line);
} …Run Code Online (Sandbox Code Playgroud) 所以我刚刚开始使用Frege和Haskell.我有使用函数式语言的经验,因为我现在使用Clojure已有几年了.我想尝试的第一件事就是我在Fibonacci数字上的常用方法.
next_fib (a, b) = (b, a + b)
fibs = map fst $ iterate next_fib (0, 1)
fib x = head $ drop x fibs
Run Code Online (Sandbox Code Playgroud)
这就是弗雷格的结果.它有效,但对于非常高的数字,例如(fib 4000),它会抛出StackOverflow错误.这让我感到惊讶,因为Clojure中的相同功能可以正常工作.这是一个Frege错误还是我得到了整个懒惰的评估错误?
该程序在GHC下正确编译和运行:
type Church a = (a -> a) -> a -> a
ch :: Int -> Church a
ch 0 _ = id
ch n f = f . ch (n-1) f
unch :: Church Int -> Int
unch n = n (+1) 0
suc :: Church a -> Church a
suc n f = f . n f
pre :: Church ((a -> a) -> a) -> Church a
pre n f a = n s z id
where …Run Code Online (Sandbox Code Playgroud) frege ×10
haskell ×4
java ×2
clojure ×1
converters ×1
fibonacci ×1
interop ×1
option-type ×1
quickcheck ×1