gpt4 book ai didi

haskell - 为什么 Haskell(有时)被称为 "Best Imperative Language"?

转载 作者:行者123 更新时间:2023-12-03 05:12:27 24 4
gpt4 key购买 nike

(我希望这个问题是切中主题的——我尝试寻找答案,但没有找到明确的答案。如果这恰好偏离主题或已经得到回答,请审核/删除它。 )

我记得曾多次听到/读过关于 Haskell 是最好的命令式语言的半开玩笑的评论,这当然听起来很奇怪,因为 Haskell 通常以其功能性而闻名 功能。

所以我的问题是,Haskell 的哪些品质/特性(如果有的话)有理由证明 Haskell 被视为最佳命令式语言 - 或者它实际上更像是一个笑话?

最佳答案

我认为这半真半假。 Haskell 具有惊人的抽象能力,其中包括对命令式想法的抽象。例如,Haskell 没有内置的命令式 while 循环,但我们可以直接编写它,现在它可以了:

while :: (Monad m) => m Bool -> m () -> m ()
while cond action = do
c <- cond
if c
then action >> while cond action
else return ()

这种抽象级别对于许多命令式语言来说都是困难的。这可以用具有闭包的命令式语言来完成;例如。 Python 和 C#。

但 Haskell 还具有(高度独特的)能力,可以使用 Monad 类来描述允许的副作用。例如,如果我们有一个函数:

foo :: (MonadWriter [String] m) => m Int

这可能是一个“命令式”函数,但我们知道它只能做两件事:

  • “输出”字符串流
  • 返回一个整数

它无法打印到控制台或建立网络连接等。结合抽象能力,您可以编写作用于“产生流的任何计算”等的函数。

Haskell 的抽象能力使其成为一种非常优秀的命令式语言。

然而,错误的一半是语法。我发现 Haskell 非常冗长并且难以以命令式方式使用。这是使用上面 while 的命令式计算示例循环,查找链表的最后一个元素:

lastElt :: [a] -> IO a
lastElt [] = fail "Empty list!!"
lastElt xs = do
lst <- newIORef xs
ret <- newIORef (head xs)
while (not . null <$> readIORef lst) $ do
(x:xs) <- readIORef lst
writeIORef lst xs
writeIORef ret x
readIORef ret

所有 IORef 垃圾、双重读取、必须绑定(bind)读取结果、fmapping ( <$> ) 来操作内联计算的结果......这一切看起来都非常复杂。从功能的角度来看,这很有意义,但命令式语言往往会隐藏大部分细节,以使它们更易于使用。

诚然,也许如果我们使用不同的 while -风格的组合器会更干净。但是,如果您将这种哲学运用得足够远(使用一组丰富的组合器来清楚地表达自己),那么您将再次达到函数式编程。命令式 Haskell 并不像设计良好的命令式语言那样“流畅”,例如 python 。

总之,通过语法改进,Haskell 很可能是最好的命令式语言。但是,根据整容的本质,它将用外部美丽和虚假的东西取代内部美丽和真实的东西。

编辑:对比 lastElt用这个Python音译:

def last_elt(xs):
assert xs, "Empty list!!"
lst = xs
ret = xs.head
while lst:
ret = lst.head
lst = lst.tail
return ret

行数相同,但每行的噪音要少得多。

<小时/>

编辑2

就其值(value)而言,Haskell 中的纯粹替换看起来是这样的:

lastElt = return . last

就是这样。或者,如果你禁止我使用 Prelude.last :

lastElt [] = fail "Unsafe lastElt called on empty list"
lastElt [x] = return x
lastElt (_:xs) = lastElt xs

或者,如果您希望它适用于任何 Foldable 数据结构并认识到您实际上并不需要 IO处理错误:

import Data.Foldable (Foldable, foldMap)
import Data.Monoid (Monoid(..), Last(..))

lastElt :: (Foldable t) => t a -> Maybe a
lastElt = getLast . foldMap (Last . Just)

Map ,例如:

λ➔ let example = fromList [(10, "spam"), (50, "eggs"), (20, "ham")] :: Map Int String
λ➔ lastElt example
Just "eggs"

(.)运算符是 function composition .

关于haskell - 为什么 Haskell(有时)被称为 "Best Imperative Language"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622524/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com