在Haskell中使用let

pro*_*eek 4 haskell variable-assignment

我在Haskell中有这个代码.

import Data.List

main = do
    putStrLn $ "\nVerify if Exists in a String"
    let wordlist = ["monad", "monoid", "Galois", "ghc", "SPJ"]
    let tweet = "This is an example tweet talking about SPJ interviewing with Galois"
    print $ map (flip isInfixOf tweet) wordlist
Run Code Online (Sandbox Code Playgroud)

没有let,我有这个错误信息:10_things.hs:16:14: parse error on input ‘=’.

这是另一个工作正常的代码.

import Data.List

wordlist = ["monad", "monoid", "Galois", "ghc", "SPJ"]
tweet = "This is an example tweet talking about SPJ interviewing with Galois"      
main = do
    putStrLn $ "\nVerify if Exists in a String"
    print $ map (flip isInfixOf tweet) wordlist
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我有错误parse error (possibly incorrect indentation or mismatched brackets).我的问题是何时何时不在letHaskell中使用?

Ørj*_*sen 10

声明/等式需要在a letwhere块内.你不需要let在模块的顶层,它是where由它的module声明启动它本身作为一个块.不包含显式module标头的模块会隐式

module Main (main) where
Run Code Online (Sandbox Code Playgroud)

在开始.

顺便说一下,缩进let块可以包含多个声明:let只要方程垂直排列,就不需要代码中的第二个.


Tik*_*vis 8

Haskell有两种引入名称的方法:letwhere.

let只要你有一个正常的表达式就可以使用.这可以出现在两个地方:如果你正在定义一个正常的值,如果你在内部的符号.在第一种情况下,您将使用let ... in在单个表达式中引入名称:

myFoo = let x = 10 ^ 10 in x + x
Run Code Online (Sandbox Code Playgroud)

在内部注释,你不需要in; 相反,let它就像一个正常的"声明"一样占据一条线.这是你的第一个例子:

main = do
  let x = something
  ...
Run Code Online (Sandbox Code Playgroud)

引入名称的另一种方法是使用where子句,这些子句不在表达式之内.程序的顶层 - 您在模块中定义所有全局可见的名称 - 在一个where块中,这就是为什么你只是在name = expression没有a的情况下编写的let.发生这种情况是因为您的模块隐含了

module Main where
Run Code Online (Sandbox Code Playgroud)

即使你没有自己写,也要在上面.

您还可以where在不同的范围内编写自己的块,这样您也可以在不使用let以下内容的情况下定义名称:

foo x = ...
  where helperA = something
        helperB = something
Run Code Online (Sandbox Code Playgroud)