需要最简单的Haskell程序

6

有人能提供不到五行的代码吗?我可以将其存为.hs文件,并作为Haskell程序运行,看看神奇的事情会发生什么?有时互联网太复杂了。


4
既然您要求“最简单”的程序,那么这就是一个例子:echo "main = return ()" | runhaskell。请注意,这是一条命令,它将在终端中运行,并利用了Haskell编程语言的特性。我将其翻译为:“回显'main = return()'并通过runhaskell运行”。 - David
10个回答

12

2
我试图写出完全相同的答案。 - rekire

11

应该有人提到了 interact,它简单易用而且实际可行:

main = interact reverse 
$ cat interact.hs | runhaskell interact.hs
esrever tcaretni = niam

并因此

main = interact (unwords . reverse . words)
$ cat interact.hs | runhaskell interact.hs
words) . reverse . (unwords interact = main

或者使用import导入:

import Data.List
 main = interact (intersperse '\n')
$ echo "hello" | runhaskell interact.hs
h
e
l
l
o

或者,现在进行编译:

main = interact showCharcount 
  where showCharcount str = show (length str) ++ "\n"
$ ghc --make -O2 interact.hs -o charcount
$ echo "hello world" | ./charcount
12

在某些情况下,开始进行一些简单的贫民版基准测试是有意义的:

$ time cat /usr/share/dict/words | ./charcount
2486813
real 0m0.096s

7

该回答更加专注于“看魔术发生”:

data Expression = Greeting | Leaving

f :: Expression -> String
f Greeting = "Hi there!"
f Leaving  = "Ok, bye!"

main = putStrLn (f Greeting)

5
所有的斐波那契数列怎么样?为了简洁起见,您可以打印其中的100个。 ;)
fibs = 1 : scanl (+) 1 fibs
main = print $ take 100 fibs

4

Hamming数是指没有任何大于5的质因数的数字。即它们的形式为2^i*3^j*5^k。前20个Hamming数如下:

[1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36]

第五十万个是:
1962938367679548095642112423564462631020433036610484123229980468750

计算后打印出第500000个数字的程序是:

merge xxs@(x:xs) yys@(y:ys) =
  case (x`compare`y) of
    LT -> x:merge xs yys
    EQ -> x:merge xs ys
    GT -> y:merge xxs ys

hamming = 1 : m 2 `merge` m 3 `merge` m 5
  where
    m k = map (k *) hamming

main = print (hamming !! 499999)

这段代码比你想要的5行还要长。当然,它可以被压缩,但我更愿意自然地编写它,并查看在任何其他语言中计算该数字需要多少行代码以及合理的执行时间。


3
输出每一个数字:
main = mapM_ print [1..]

“print” 自动添加新行,因为它等同于 “putStrLn . show”,所以它将在所有缓冲方案下显示输出。我也刚刚测试了每个缓冲方案,以确保其可用。 - Gabriella Gonzalez

3

您可以变得开心起来。这里的greet是一个函数,它接收一个名字并将其转换为问候语:

greet xs = "\nHello, " ++ xs

main = do
   putStrLn $ unlines ["Hi! I'm a Haskell program.", "Who are you?"]
   fmap greet getLine >>= putStrLn

main使用unlines将字符串列表转换为单个以换行符分隔的字符串,然后使用putStrLn打印出来。 getLine返回用户输入的文本行(不包括换行符),然后应用greet。最后,我们将其作为输入推送到另一个putStrLn中。


3

我期待着深入学习这个教程。谢谢Demas。 - Emanegux

2

这个有点复杂,绝对不是最简单的,但它使用了无限列表[1..],你可以称之为魔法。

described name list = putStrLn ("\n" ++ name) >> mapM_ print (zip [1..] list)
main = let somenums = [1..100] in do
   described "Some cubes:" [ x^3 | x <- somenums]
   described "Some powers:" $ map (2^) somenums
   described "Some triangle numbers:" $ scanl (+) 0 somenums

described 函数会先打印出描述,再将列表与它们的位置配对(zip)进行打印输出。
我将其应用于一些数字序列。整数数据默认为 Integer,这就是为什么它可以愉快地告诉你 2^100 的原因。但是 Int 数据类型更为有限,(maxBound :: Int == 2147483647),但当然需要更少的时间和空间。


哇,那真是强大。可能对我的大脑来说有点太难处理了,哈哈。但我会在不久的将来回到这个评论。谢谢AndrewC! - Emanegux

1

Tutorials/Programming Haskell/String IO的笔记中可以看到,有多个简短且简单的启动示例;例如,相当于bash命令cat < myFile.txt的等效示例。

main = interact id

其中interact将一个函数(在本例中是恒等函数id)应用于标准输入(此处为myFile.txt)中的内容。

按以下方式编译和运行它:

ghc --make short.hs
./short < myFile.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接