【问题标题】:simplifying maybe Monad简化也许 Monad
【发布时间】:2013-07-25 18:38:43
【问题描述】:

我试图理解 也许 Monad 但我看到的大多数示例都使用了一些特定于语言的功能。为了确保我在概念上理解它是正确的,我想编写一个通用实现。下面是我想出的。

有人可以告诉我在概念上是否正确吗?有没有更好的方法来概括它?

def f():
    return 2

def g():
    return 4

def h():
    return 7

def i():
    return None

def bind(val, func):
    if val is None:
        return None
    else:
        return(func())

unit = 0

>>> bind(bind(bind(unit,f),i),h) #Returns nothing
>>> bind(bind(bind(unit,f),g),h) #Returns a value
>>>7 

如果我想从这些函数中添加值并在其中任何一个为 NULL 时中止;有什么建议吗?

【问题讨论】:

  • @Joehillen 这根本不是真的。 Monad 在动态类型语言中确实非常有用。
  • @Matt Fenwick 怎么样?没有任何类型。你在 monad 中包装了什么?
  • @Joehillen:动态类型语言确实有类型。你认为type 函数有什么作用?
  • @Joehillen 动态/静态类型和强/弱类型相互独立。你可以拥有一个强类型和动态类型的语言; Python 和 Ruby 都是很好的例子。

标签: python haskell monads


【解决方案1】:

你很亲密,但是bind的签名是

m a -> (a -> m b) -> m b

所以它“解包”m 并将包含的值传递给下一个函数。你目前有

m a -> ( () -> m b) -> m b

由于您只是忽略了 val 绑定获取,因此您应该有

def bind(val, func):
    if val is None:
        return None
    else:
        return(func(val))

这相当于 Haskell 中的 >>=。你之前的 >> 应该被实现为

# "ignore" bind
def ibind(val, func):
    bind(val, lambda _ : func())

它只是愉快地丢弃了bind 的值。

为了更进一步,你必须引入一个类

class Maybe():
    def __init__(v):
        self.val = v
        self.isNothing = False
Nothing = Maybe(None)
Nothing.isNothing = True

def bind(val, func):
    if val.isNothing:
        return Nothing
    else:
        return(func(val.val))

【讨论】:

  • 你如何区分NothingJust Nothing
  • @Joehillen 你不能,但作为理解单子的概念示例,我认为这很好
  • @jozefg 非常感谢您的回复。我知道 bind 的一般签名,但我的困惑是(现在仍然是)我的函数(f、g 和其他函数)不接受任何输入参数,所以我不能执行 func(val),那我该怎么办?
  • @DevMaha 更改您的函数,以便它们接受参数或将您的函数与ibind 一起使用,而不是bind
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-20
  • 2019-02-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
相关资源
最近更新 更多