what happens when executing `(read “[Red]”) :: [Color]` under ghci?

那年仲夏 提交于 2020-01-05 02:33:52

问题


I am reading the subsection of Real World Haskell Chapter 6 (typeclasses) about aninstance of Read for Color, which implements readsPrec function. I don't know what happens when I type (read "[Red]") :: [Color] in GHCi, getting a [Red] result.

For simplicity, I changed this implementation of the function a little, as shown below:

instance Read Color where
     readsPrec _ value = [(Red, drop (length "Red") value)]

Now, my confusion is: in GHCi, we can use the above as follows:

*Main> let readsPrec 2 "Red]" = [(Red, drop (length "Red") "Red]")]
*Main> readsPrec 2 "Red]"
       [(Red,"]")]

Why readsPrec _ value = [(Red, drop (length "Red") value)] return [Red] when executing (read "[Red]") :: [Color]?


回答1:


There is an interaction going on between two instances of readsPrec:

  1. the readsPrec you defined for instance Read Color
  2. the readsPrec defined by the Prelude for instance Read [a]

Let's call the readsPrec in #2 readsPrecList.

When evaluating

read "[Red]" :: [Color]

what first happens is the readsPrecList is called. That function gobbles up the leading square paren and calls your readsPrec with the input string "Red]". Your function drops the first three characters and returns back to readsPrecList with the value Red and input string set to "]". That function checks that the next character is a closing square bracket and returns back your value in a list - i.e. [Red].

Why does evaluation begin with a call to readPrecList? Because you are asking read to create a list of something.

Why does readsPrecList call the readsPrec for the type Color? Because you asked read to create a list of Color values.

This is an example of type-directed dispatch - the instance of readsPrec called is determined by the type of the value being requested.



来源:https://stackoverflow.com/questions/27442288/what-happens-when-executing-read-red-color-under-ghci

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!