从 'Maybe a' return 中获取 'a' 值 输入 Haskell
Getting 'a' value from 'Maybe a' return type in Haskell
我有一个 Haskell 函数 eval :: WExp -> Memory -> WValue
,它有一堆不同的实例用于不同的情况。目前,关于 WExp
、Memory
和 WValue
的知识与此无关。我的问题是,对于 eval
的特定实例,我正在使用 lookup
函数,它采用 eval
的参数(在本例中为字符串)搜索键列表-该字符串的值对。请注意,此 lookup
函数不是 Prelude 中包含的函数;它是在 .hs 文件中自定义的。如果找到该字符串,则与其关联的值是 returned,但如果未找到,则 Nothing
是 returned。由于 Nothing
的情况,lookup
的类型实际上是 Maybe a
,其中 a
在这种情况下将是 WValue
。因为 eval
会 return 一个 Maybe WValue
,编译器显然会抱怨类型不是 WValue
.
我认为可能有某种通用方法可以从 returns Maybe a
.
的任何函数中提取 a
值
如果您知道查找成功,并且 Maybe a
实际上是 Just a
,您可以简单地进行模式匹配:
let (Just val) = lookup ...
你的 Maybe a
中有你的 val::a
。请注意,这是不安全的代码,如果 lookup
returns a Nothing
.
将不正常地抛出错误
这样做
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
就会崩溃。 "crash real hard" 我的意思是,如果你幸运的话,你会得到一个分段错误,如果你不幸运,你会在网络上发布你的私钥。
{-# 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)
好吧,你让自己陷入了泥潭,因为你的 lookup
类型表明它可能会失败。 Haskell 在这种情况下迫使您处理发生此类故障的可能性。如果lookup
returns Nothing
.
是这样的
如果你真的确定lookup
永远不会失败(可能是因为你对程序进行了预处理和类型检查,或者你真的相信它:))你可以使用 Data.Maybe
中的 fromJust
。请注意,这实际上只是一个创可贴解决方案,因为如果使用 Nothing
调用 fromJust
将 自行产生 (Haskell) 运行时错误.
您要查找的函数是 maybe
在 Prelude 中定义的。
如果表达式为 Nothing,您需要决定要 return 什么。比方说你想得到空字符串 ""
什么都没有。那么下面的内容会让你跳出 Maybe 的盒子。
Prelude> maybe "" id (Just "hello")
"hello"
Prelude> maybe "" id (Nothing)
""
我有一个 Haskell 函数 eval :: WExp -> Memory -> WValue
,它有一堆不同的实例用于不同的情况。目前,关于 WExp
、Memory
和 WValue
的知识与此无关。我的问题是,对于 eval
的特定实例,我正在使用 lookup
函数,它采用 eval
的参数(在本例中为字符串)搜索键列表-该字符串的值对。请注意,此 lookup
函数不是 Prelude 中包含的函数;它是在 .hs 文件中自定义的。如果找到该字符串,则与其关联的值是 returned,但如果未找到,则 Nothing
是 returned。由于 Nothing
的情况,lookup
的类型实际上是 Maybe a
,其中 a
在这种情况下将是 WValue
。因为 eval
会 return 一个 Maybe WValue
,编译器显然会抱怨类型不是 WValue
.
我认为可能有某种通用方法可以从 returns Maybe a
.
a
值
如果您知道查找成功,并且 Maybe a
实际上是 Just a
,您可以简单地进行模式匹配:
let (Just val) = lookup ...
你的 Maybe a
中有你的 val::a
。请注意,这是不安全的代码,如果 lookup
returns a Nothing
.
这样做
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
就会崩溃。 "crash real hard" 我的意思是,如果你幸运的话,你会得到一个分段错误,如果你不幸运,你会在网络上发布你的私钥。
{-# 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)
好吧,你让自己陷入了泥潭,因为你的 lookup
类型表明它可能会失败。 Haskell 在这种情况下迫使您处理发生此类故障的可能性。如果lookup
returns Nothing
.
如果你真的确定lookup
永远不会失败(可能是因为你对程序进行了预处理和类型检查,或者你真的相信它:))你可以使用 Data.Maybe
中的 fromJust
。请注意,这实际上只是一个创可贴解决方案,因为如果使用 Nothing
调用 fromJust
将 自行产生 (Haskell) 运行时错误.
您要查找的函数是 maybe
在 Prelude 中定义的。
如果表达式为 Nothing,您需要决定要 return 什么。比方说你想得到空字符串 ""
什么都没有。那么下面的内容会让你跳出 Maybe 的盒子。
Prelude> maybe "" id (Just "hello")
"hello"
Prelude> maybe "" id (Nothing)
""