ここにいくつかの問題があります。まず、中括弧の前にレコード名を指定する必要があります。だからあなたは望みます
(>>=) (Val {getVal = l}) f = Val {getVal = map f l}
今、いずれの機能もタイプチェックを行っていません。しかし、あなたが既に存在するリストモナドインスタンスに委任しているだけなので、修正はそれほど難しくありません。 return
は近いですが、結果をリストにラップする必要があります。
return x = Val [x]
同様に、map
はレコード内には入れません。あなたは(>>=)
のリストのモナドバージョンが欲しいです。
(>>=) (Val {getVal = l}) f = Val {getVal = l >>= f}
残念ながら、これはまだないかなりです。TypeCheck、f
以来Val
ない[]
を返すように設計されています。モナド操作の中でその修正を行う必要があります。
(>>=) (Val {getVal = l}) f = Val {getVal = l >>= getVal . f}
その後、あなたはおそらくApplicative
がMonad
のスーパークラスであることについて、エラーを取得します。これは、いくつかのヘルパー関数を簡単に適用することで解決できます。
import Control.Monad
-- ...
instance Functor Val where
fmap = liftM
instance Applicative Val where
pure = return
(<*>) = ap
すべてコンパイルする必要があります。サイドノートとして
あなたはGHCを使用している場合、自動的にnewtype
データ型に対してあなたのインスタンスを与えるGeneralizedNewtypeDeriving
と呼ばれる便利な機能があります。あなたはnewtype
、ないdata
にそう
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype Val a = Val {getVal :: [a]}
deriving (Show, Functor, Applicative, Monad)
これだけ作品のようにそれを使用することができ、それが唯一のGHCで動作しますので、あなたのコードを意図している場合、コンパイラ間で移植できるようにそれを使用しないでください。
'return'の定義はタイプチェックではありませんか? – Carl