入門 - たぶんPythonで "種類の"モナド



haskell 入門 (5)

Pythonには、特にモナドの構文がありません。 あなたがMaybeモナドのようなものを使うことに自分自身を制限したいのであれば( Maybeしか使えMaybeという意味で、モナドを扱う汎用関数を作ることはできません)、あなたは次のアプローチ:

class Maybe():
    def andThen(self, action): # equivalent to Haskell's >>=
        if self.__class__ == _Maybe__Nothing:
            return Nothing
        elif self.__class__ == Just:
            return action(self.value)

    def followedBy(self, action): # equivalent to Haskell's >>
        return self.andThen(lambda _: action)

class _Maybe__Nothing(Maybe):
    def __repr__(self):
        return "Nothing"

Nothing = _Maybe__Nothing()

class Just(Maybe):
    def __init__(self, v):
        self.value = v
    def __repr__(self):
        return "Just(%r)" % self.value

次に、現在返されているメソッドをすべてNoneにして、 Just(value)またはNothing返します。 これにより、このコードを書くことができます:

Person.find(id=12345).andThen(lambda person: Company.find(person.companyId)).andThen(lambda company: Country.find(company.countryId))

もちろん、中間結果を変数に格納するためにラムダを適合させることができます。 それを正しく行う方法はあなた次第です。

https://ffff65535.com

私のコードのいくつかをクリーンアップする方法を見つけようとしています。

ですから、私はPythonコードの中にこういうものを持っています:

company = None
country = None

person = Person.find(id=12345)
if person is not None: # found        
    company = Company.find(person.companyId)

    if company is not None:
         country = Country.find(company.countryId)

return (person, company, country)

ハスケルのモナド(特にMaybe )のチュートリアルを読んで、私は別の方法でそれを書くことができるのだろうかと思っていました。


あなたはPyMonadをチェックしましたか?

https://pypi.python.org/pypi/PyMonad/

Maybeモナドだけでなく、リストモナド、Functor、Applicative Functorクラスも含まれています。 モノイドなど。

あなたの場合、それは次のようなものになります:

country = Person.find(id=12345)          >> (lambda company: 
          Company.find(person.companyId) >> (lambda country: 
          Country.find(company.countryId))

EAFPよりも理解しやすく、よりクリーンです。


短絡動作を利用し、カスタムオブジェクトはデフォルトでtrue、 Noneはfalseです。

person  = Person.find(id=12345)
company = person and person.company
country = company and company.country


person = Person.find(id=12345)
company = None if person is None else Company.find(person.companyId)
country = None if company is None else Country.find(company.countryId)

return (person, company, country)




haskell