为什么我可以使用`>> =`而不使用显式或隐式定义?

时间:2015-08-29 00:07:31

标签: haskell monads typeclass type-systems

我已将类型//create a default format that you reset the whole text field to every time you check var defaultTf:TextFormat = txt.defaultTextFormat; function highlightWord(word:String, caseSensitive:Boolean = false){ //the current text of the input text field var textBlock:String = txt.text; //lower case everything if you don't want case sensitivity if(!caseSensitive){ word = word.toLocaleLowerCase(); textBlock = textBlock.toLocaleLowerCase(); } //an array to store all the starting indexes of the word var arr:Array = new Array(); //helper vars for the loop below var curIndex:int = 0; var foundIndex:int; //loop so long as the word is found (the found index is 0 or greater) while(foundIndex > -1){ foundIndex = textBlock.indexOf(word, curIndex); if(foundIndex > -1){ //add the index of the found word to the array arr.push(foundIndex); //increment the index by word length curIndex = foundIndex + word.length; } } //create a text format to use to highlight the words (blue) var tf:TextFormat = new TextFormat(null,null,0x0000FF); //set everything to the default style txt.setTextFormat(defaultTf); //loop through the array of words, and highlight them with the text format for(var i:int=0;i<arr.length;i++){ txt.setTextFormat(tf, arr[i],arr[i] + word.length); } } highlightWord("addEventListener"); 定义为

X

我制作了newtype X i o = X { runX :: Int -> i -> IO o } FunctorApplicative的实例

Monad

正如您可能已经说过的那样,因此我无法提出instance Functor (X i) where fmap f a = X $ \ i o -> liftA f $ runX a i o instance Applicative (X i) where pure x = X $ \ _ _ -> return x a <*> b = X $ \ i o -> liftA2 (<*>) (runX a i o) (runX b i o) instance Monad (X i) where return = pure a >> b = X $ \ i o -> runX a i o >> runX b i o 的定义,因此将其排除在外。我预计这会在编译时出错,但事实上,它所做的只是提出警告。很好,所以它不会检查是否定义了类的所有方法,但是当然我实际上不能使用 >>=。不,再次错了。令我惊讶的是,GHCi愉快地评估>>=let x = pure 5 >>= pure不导出Control.Monad的默认定义,我当然没有定义一个,所以这怎么可能?

1 个答案:

答案 0 :(得分:9)

鉴于您的更正定义,如果我尝试定义然后使用x,我会得到预期的运行时异常:

λ> let x = pure 5 >>= pure :: X Int Int
λ> runX x 5 5
*** Exception: foo.hs:12:10-20: No instance nor default method for class operation GHC.Base.>>=

有两种可能的原因,你不会看到它。

首先,您刚刚运行了let,但从未尝试过评估结果。由于Haskell很懒惰,let x = ...实际上并没有做任何事情。 x只会在您真正尝试使用时进行评估(例如,runX),以便在您遇到错误时进行评估。

另一种可能性是您使用let而未指定类型:

λ> let x = pure 5 >>= pure
λ> x
5

此处,x在其使用的monad m中具有多态性。要打印对此类多态术语有用的内容,ghci默认mIO,它可以正常工作并为您提供5,但不会告诉您有关自定义monad的任何有用信息。