获得' a'价值来自'也许是'在Haskell中返回类型

时间:2015-02-24 21:39:00

标签: haskell maybe

这很难解释,因为整个代码有很多背景细节,需要知道才能真正了解我正在谈论的内容。但是我会尽力让我的主要观点得到解决,并希望它足够了。如果没有,请告诉我,我会添加更多信息。所以:

我有一个Haskell函数eval :: WExp -> Memory -> WValue,它有一堆不同的自身实例用于不同的情况。目前,有关WExpMemoryWValue的相关信息并不相关。我的问题是,对于eval的特定实例,我使用lookup函数,该函数采用eval的参数(在这种情况下为字符串)搜索密钥列表 - 该字符串的值对。请注意,此lookup函数不是Prelude中包含的函数;它是在.hs文件中自定义的。如果找到该字符串,则返回与其关联的值,但如果未找到,则返回Nothing。由于Nothing案例,lookup的类型实际为Maybe a,其中a在这种情况下为WValue。由于eval会返回Maybe WValue,因此编译器显然会抱怨该类型不是WValue

同样,如果您需要有关这些其他类型的更多信息,我可以提供。我只想到可能有某种通用方法从任何返回a的函数中提取Maybe a值。如果没有,我想我会在别处寻找解决方案:)

4 个答案:

答案 0 :(得分:7)

这样做

do
   input <- getUserInput
   result <- lookup input structure
   case result of
     Just a -> putStrLn $ "I'm so happy you chose "++show a++"."
     Nothing -> putStrLn $ "So sorry; "++input++" is not a valid option."

不要这样做

do
   input <- getUserInput
   result <- lookup input structure
   case result of
     Just a -> putStrLn $ "I'm so happy you chose "++show a++"."
     Nothing -> error $ input ++ " is not a valid option."

这很糟糕,因为如果用户输入错误,你的程序就会出现问题。

真的不这样做

有一个名为fromJust的函数尝试从Maybe中提取值,如果找到Nothing则会抛出错误。它看起来像

fromJust :: Maybe a -> a
fromJust (Just a) = a
fromJust Nothing = error "Oops, you goofed up, fool."

这使得很难看出出了什么问题。

而且,真的不会这样做

但是如果你想玩火,你可以尝试它只是为了好玩。这将尝试从Maybe中获取值,如果找到Nothing则会严重崩溃。通过&#34;崩溃真的很难&#34;我的意思是,如果你很幸运,你会遇到分段错误,如果你不是,你就会在网上发布你的私钥。

{-# LANGUAGE GADTs, DataKinds, KindSignatures #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}

module Unsafe.FromJust (unsafeFromJust) where

-- Clear sign of bad news
import Unsafe.Coerce (unsafeCoerce)

-- This creates a "closed kind" with types
-- 'JustType and 'NothingType. You could just
-- define datatypes called JustType and NothingType,
-- but this makes the intent clearer.
data MaybeType = JustType | NothingType

data M (t::MaybeType) a where
  -- The order of these constructors must not
  -- be changed, because this type must look,
  -- at runtime, exactly like a Maybe
  N :: M 'NothingType a
  J :: a -> M 'JustType a

-- A safe sort of fromJust for M.
fromJ :: M 'JustType a -> a
fromJ (J a) = a

-- Really, seriously unsafe.
unsafeFromJust :: Maybe a -> a
unsafeFromJust m = fromJ (unsafeCoerce m)

答案 1 :(得分:5)

如果您知道查找成功,并且Maybe a实际上是Just a,则可以简单地模式匹配:

let (Just val) = lookup ...

你的val::a中有Maybe a。请注意,这是不安全的代码,如果lookup返回Nothing,则会无法正常抛出错误。

答案 2 :(得分:1)

您要查找的功能是在Prelude中定义的maybe

如果表达式为Nothing,则需要决定返回什么。假设您想获取空字符串""为Nothing。然后,以下内容将使您摆脱Maybe框框。

Prelude> maybe "" id (Just "hello")
"hello"
Prelude> maybe "" id (Nothing)
""

答案 3 :(得分:0)

嗯,你陷入了泥潭,因为lookup的类型表明它可能会失败。在这种情况下,Haskell会强迫您处理发生此类故障的可能性。如果lookup返回Nothing,则会出现这种情况。

如果你确实确定lookup永远不会失败(可能是因为你对程序进行了预处理和类型检查,或者你真的相信它:),你可以使用{{1}来自fromJust。请注意,这实际上只是一个创可贴解决方案,因为如果使用Data.Maybe调用fromJust 自行生成(Haskell)运行时错误。