【发布时间】:2016-08-17 13:58:27
【问题描述】:
我最近开始学习Elixir,我真的很喜欢它,但它是我用过的第一个函数式编程语言。我面临的问题来自我一直在阅读教程和观看LearnElixir 的截屏视频,您应该尽量避免使用IF 类型语句。
但我发现自己经常嵌套 cond 或 case
我会用其他语言(如 Golang 或 Javascript)解决这些解决方案,只需使用带有提前返回的 if 语句,这样超出此范围的代码就不会运行,这使我在 99% 的时间都不必嵌套条件只是检查虚假值并返回。
那么在Elixir(或其他函数式编程语言)中,您将如何在不使用嵌套并利用语言功能的情况下以适当的方式编写类似下面的内容。
def loginPost(conn, %{"user" => user_params}) do
# Look for user in database
query = from u in User,
where: u.email == ^user_params["email"],
select: [u.email, u.username, u.password]
data = Repo.all(query)
# Check to see if a user had been found
case (length data) == 0 do
true -> # No user was found, send an error message
conn
|> json(%{ success: false, errors: ["Wrong username or password"]})
false -> # A user was found, compare password
[[email, username, db_password]] = data
case Comeonin.Bcrypt.checkpw(user_params["password"], db_password) do
true -> # Password was correct, set session and return a json response
conn
|> put_session(:authenticated, true)
|> put_session(:username, username)
|> put_session(:email, email)
|> json(%{success: true}) # Send json response and redirect on client side
false -> # Password was incorrect, send an error message
conn
|> json(%{success: false, errors: ["Wrong username or password"]})
end
end
end
end
【问题讨论】:
-
我更好奇为什么应该避免 if 的原因......这根本没有意义。在任何语言中,分支都是程序的构建块。在一个重要的程序中一定有一些分支发生。
-
@HuStmpHrrr 我在 Elixir 的 IRC / Slack 上与我交谈过的一些人通常会说,哦,如果我太嵌套了,我想我在一个函数中做了太多事情,只会再写一个
-
那是另一回事。它适用于所有语言,即避免过于嵌套的结构。在 fp 中,没有循环结构,所以批评者都会指向分支。我明白了。它更多地是关于模块化。不仅仅是出于某种原因避免某些特定的结构。我认为如果使用
if,这段代码会更好。 -
@HuStmpHrrr By Code 你的意思是上面给出的例子吗?
-
是的。布尔值的模式匹配很奇怪。但匹配一组布尔值是一种常见(也是很好)的做法。
标签: functional-programming elixir