从Haskell的'Maybe a'返回类型获得'a'值 [英] Getting 'a' value from 'Maybe a' return type in Haskell

查看:230
本文介绍了从Haskell的'Maybe a'返回类型获得'a'值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这很难解释,因为我们需要了解如何从功能上真正了解我所谈论的代码的整体背景细节。但我会尽我所能去解决我的主要观点,并希望这已经足够了。如果不是,请告诉我,我会添加更多信息。所以:

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

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

解决方案

做到这一点



  do 
输入< - getUserInput
结果< - 查找输入结构
结果
只是一个 - > putStrLn $我很高兴你选择了++ show a ++。
Nothing - > putStrLn $很抱歉;++ input ++不是一个有效的选项。



不要这样做



  do 
输入< - getUserInput
结果< - 查找输入结构
结果
只是 - > putStrLn $我很高兴你选择了++ show a ++。
Nothing - >错误$ input ++不是一个有效的选项。

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

b
$ b

真的不这样做



有一个函数叫做来自Just 它尝试从 Maybe 中提取值,如果找到 Nothing ,则会引发错误。它看起来像

  fromJust :: Maybe a  - >来自Just(a)的a 
= a
来自Just Nothing =错误糟糕,你疯了。

这使得很难看出哪里出了问题。



真的, 不这样做



但是如果你想玩火,你可以尝试一下乐趣。这将尝试从 Maybe 中获取一个值,如果发现 Nothing ,就会很难实现。通过真正的崩溃我的意思是,如果你幸运的话,你会得到一个分段错误,如果你没有,你会在网上发布你的私钥。

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

模块Unsafe.FromJust(unsafeFromJust)其中

- 清除坏消息的标志
导入Unsafe.Coerce(unsafeCoerce)

- 创建一个closed kind类型
- 'JustType和'NothingType
data MaybeType = JustType | NothingType

data M(t :: MaybeType)a where
- 这些构造函数的顺序一定不能变为
- 因为这个类型必须显示
- 在运行时,完全像一个Maybe
N :: M'NothingType a
J :: a - > M'JustType a

- 从J :: M'JustType a - >来自J(J a)的
= a

- 真的,严重不安全。
unsafeFromJust ::也许a - > a
unsafeFromJust m = fromJ(unsafeCoerce m)


This is going to be hard to explain because there is a decent amount of background detail about the code as a whole that needs to be known to really know functionally what I'm talking about. But I'll try my best to just get my main point across, and hope that it's enough. Let me know if not and I'll add more information. So:

I have a Haskell function eval :: WExp -> Memory -> WValue with a bunch of different instances of itself for different cases. For now, knowledge about WExp, Memory, and WValue is not relevant. My problem is that, for a specific instance of eval, I am using a lookup function, which takes the parameter of eval (a string in this case) searches a list of key-value pairs for that string. Note that this lookup function is not the one included in the Prelude; it is self-defined within the .hs file. If the string is found, the value associated with it is returned, but if it is not found, Nothing is returned. Because of the Nothing case, the type of lookup is actually Maybe a, where a would be a WValue in this case. Because eval would return a Maybe WValue, the compiler obviously complains that the type is not WValue.

Again, if you need more information on what these other types are, I can provide it. It is just my thought that there might be some kind of general method to extract the a value from any function that returns Maybe a. If not, I guess I'll look elsewhere for solutions :)

解决方案

Do this

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."

Don't do this

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."

This is bad because your program just goes splat if the user input is wrong.

Really don't do this

There is a function called fromJust that attempts to pull a value out of a Maybe and throws an error if it finds Nothing. It looks like

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

This makes it hard to see what went wrong.

And really, really don't do this

But if you want to play with fire, you can try it just for fun. This will attempt to get a value out of a Maybe and crash real hard if it finds Nothing. By "crash real hard" I mean you'll get a segmentation fault if you're lucky, and you'll publish your private keys on the web if you're not.

{-# 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
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)

这篇关于从Haskell的'Maybe a'返回类型获得'a'值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆