繁体   English   中英

Haskell嵌套了where子句和“let ... in”语法

[英]Haskell nested where clause and “let … in” syntax

我刚刚开始使用Haskell。

这个嵌套的where子句有什么问题?

length' a = fromIntegral (length a)

isPalin1 xs = fstHalf == reverse sndHalf
    where
        fstHalf = take halfLength xs
        sndHalf = drop halfLength xs
            where halfLength = (length' xs) / 2

我得到的错误: isPalin1.hs:5:32: Not in scope: 'halfLength'

以下也是错误的,希望有人可以告诉我原因:

length' a = fromIntegral (length a)

isPalin2 xs = fstHalf == reverse sndHalf
    where
        let
            halfLength = (length' xs) / 2
        in
            fstHalf = take halfLength xs
            sndHalf = drop halfLength xs

错误消息:

isPalin2.hs:7:17:
    parse error (possibly incorrect indentation or mismatched brackets)

正如评论中提到的那样,对于isPalin1where的范围是sndHalf ,而不是fstHalf 我将重写isPalin1示例(语法上)的方式是这样的:

isPalin1 xs = fstHalf == reverse sndHalf
  where length' a = fromIntegral (length a)
        halfLength = (length' xs) / 2
        fstHalf = take halfLength xs
        sndHalf = drop halfLength xs

这不会给你任何解析错误,并且范围都可以解决。 但是,它不会编译,因为它的逻辑是关闭的。

问题是为什么你需要从整体? 从查看代码的答案是,您正在尝试将列表拆分为一半,并且可能在尝试执行类似(length xs) / 2类的操作时更早出现编译错误。 看起来你要做的就是将列表分成两半,但这对于具有给定逻辑的奇数长度列表来说根本不起作用。 如果列表的长度为11 ,那么fstHalfsndHalf应该是什么? (fromIntrgral (length xs)) / 2会使halfLength5.5 ,但你不能从列表中取5.5元素,所以Haskell的类型系统会混淆

而不是这个,你可以使用(length xs) `div` 2进行整数除法,丢弃余数。 如果xs的长度为10 ,则返回5 如果xs的长度为11 ,则返回5 我不想给你一个完整的解决方案,以防这是一个家庭作业问题,但只要想想你如何使用整数除法来使你的程序工作。 考虑一下长度为偶数或奇数的列表将如何影响确定它们是否为回文的算法,并使您的代码考虑到这一点。

至于你得到的第二个错误:原因是你有两个函数, fstHalfsndHalf ,它们位于let语句的in子句中,导致解析错误。 一般来说,我建议避免嵌套whereif语句除非你绝对必须或你是一个受虐狂。 一个你清理逻辑,尽量坚持的例子的格式where的语句我在这篇文章开始了,这让事情变得简单许多。

并且不要放弃Haskell,它会在你身上发展。 :)

where仅适用于一个绑定,因此halfLength在你的第一个片段是只提供给sndHalf 你应该这样写:

length' a = fromIntegral (length a)

isPalin1 xs = fstHalf == reverse sndHalf
    where
        halfLength = (length' xs) / 2
        fstHalf = take halfLength xs
        sndHalf = drop halfLength xs

这是因为范围本身就where ,因此绑定可以相互引用。

至于你的第二个片段,这完全不正确。 一个let ⋯ in语句严格来说是一个表达式,并且不能在where的绑定上下文where

如果你在哪里使用let ⋯ in ,你会像这样使用它:

length' a = fromIntegral (length a)

isPalin1 xs =
    let halfLength = (length' xs) / 2
        fstHalf = take halfLength xs
        sndHalf = drop halfLength xs
    in  fstHalf == reverse sndHalf

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM