zoukankan      html  css  js  c++  java
  • GHCi Prelude学习

    参考:http://www.cse.unsw.edu.au/~en1000/haskell/inbuilt.html

    http://www.cse.unsw.edu.au/~en1000/haskell/hof.html

    在GHCi中,可以使用:type来查看对象的类型,与http://www.cnblogs.com/long123king/p/3837686.html中说到的一样,

    Haskell中,函数也是一种特殊的对象,对象就有类型,函数作为一种对象,可以作为参数传递,也可以赋值,创建和销毁。

    Prelude> :type (+)
    (+) :: Num a => a -> a -> a
    

      

    这个类似要怎么解释呢,"::"的前面是函数的名称,后面是函数对象的类型,或者说原型。

    "=>"前面的Num a是表明参数的类型,

    Prelude> :type 1
    1 :: Num a => a
    

    后面是函数的输入与输出类型声明。

    之所以会有多个->,那是因为(+)函数对象中其实包含一个更加简单的函数,比如(+) 2,这个函数的意思是“在使用(+)函数对象时,将第一个参数固定为2,这与boost中的bind类似”,而这个函数对象的类型是Num a => a->a,

    再把另外一个参数传递给这个简单的函数,得到的结果也是a类型,因此(+)是一个复合函数。

    凡是需要多个参数的函数对象,都可以分解成一步一步的简单函数组成的复合函数。

    Prelude> (+) 2
    
    <interactive>:35:1:
        No instance for (Num a0) arising from a use of `+'
        The type variable `a0' is ambiguous
        Possible fix: add a type signature that fixes these type variable(s)
        Note: there are several potential instances:
          instance Num Double -- Defined in `GHC.Float'
          instance Num Float -- Defined in `GHC.Float'
          instance Integral a => Num (GHC.Real.Ratio a)
            -- Defined in `GHC.Real'
          ...plus three others
        In the expression: (+) 2
        In an equation for `it': it = (+) 2
    
    <interactive>:35:1:
        No instance for (Show (a0 -> a0)) arising from a use of `print'
        Possible fix: add an instance declaration for (Show (a0 -> a0))
        In a stmt of an interactive GHCi command: print it
    Prelude> :type (+) 2
    (+) 2 :: Num a => a -> a
    

      

    特殊符号需要显式地用括号来表明这是个函数对象,

    对于普通的函数对象,也可以使用括号来表明其函数对象的身份。

    Prelude> :type +
    
    <interactive>:1:1: parse error on input `+'
    Prelude> :type (+)
    (+) :: Num a => a -> a -> a
    Prelude> :type names
    names :: [Char]
    Prelude> :type head
    head :: [a] -> a
    Prelude> :type (head)
    (head) :: [a] -> a
    

    再来看一个更加复杂的函数对象

    Prelude> :type map
    map :: (a -> b) -> [a] -> [b]
    

      

    这个函数对象包含了两个简单函数对象, (a -> b)是一个函数,可以将类型a的对象转换成类型b的对象;

    (a -> b) -> [a],是另外一个函数,它的意思是“在执行整体函数对象时,将第一个参数固定为[a]”。

    这种将复合函数对象(包含了多个参数的函数对象)分解成几个简单函数对象的思想,是为了支持“函数作为一种对象”的这种设计理念,

    这样就可以将上面分解出的简单的函数作为参数,传递给复合函数对象。

    比如

    Prelude> let nums = [1..100]
    Prelude> map ((*) 2) nums
    [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62,64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94,96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,126,128,130,132,134,136,138,140,142,144,146,148,150,152,154,156,158,160,162,164,166,168,170,172,174,176,178,180,182,184,186,188,190,192,194,196,198,200]
    

      

      

    虽然,像(+) 2这样的函数对象在多数时候,看起来并不是一个常见的用法。

     怎样在Prelude中得到当前运行环境的信息

    Prelude> :help
     Commands available from the prompt:
    
       <statement>                 evaluate/run <statement>
       :                           repeat last command
       :{
     ..lines.. 
    :}
           multiline command
       :add [*]<module> ...        add module(s) to the current target set
       :browse[!] [[*]<mod>]       display the names defined by module <mod>
                                   (!: more details; *: all top-level names)
       :cd <dir>                   change directory to <dir>
       :cmd <expr>                 run the commands returned by <expr>::IO String
       :ctags[!] [<file>]          create tags file for Vi (default: "tags")
                                   (!: use regex instead of line number)
       :def <cmd> <expr>           define command :<cmd> (later defined command has
                                   precedence, ::<cmd> is always a builtin command)
       :edit <file>                edit file
       :edit                       edit last module
       :etags [<file>]             create tags file for Emacs (default: "TAGS")
       :help, :?                   display this list of commands
       :info [<name> ...]          display information about the given names
       :issafe [<mod>]             display safe haskell information of module <mod>
       :kind <type>                show the kind of <type>
       :load [*]<module> ...       load module(s) and their dependents
       :main [<arguments> ...]     run the main function with the given arguments
       :module [+/-] [*]<mod> ...  set the context for expression evaluation
       :quit                       exit GHCi
       :reload                     reload the current module set
       :run function [<arguments> ...] run the function with the given arguments
       :script <filename>          run the script <filename>
       :type <expr>                show the type of <expr>
       :undef <cmd>                undefine user-defined command :<cmd>
       :!<command>                 run the shell command <command>
    
     -- Commands for debugging:
    
       :abandon                    at a breakpoint, abandon current computation
       :back                       go back in the history (after :trace)
       :break [<mod>] <l> [<col>]  set a breakpoint at the specified location
       :break <name>               set a breakpoint on the specified function
       :continue                   resume after a breakpoint
       :delete <number>            delete the specified breakpoint
       :delete *                   delete all breakpoints
       :force <expr>               print <expr>, forcing unevaluated parts
       :forward                    go forward in the history (after :back)
       :history [<n>]              after :trace, show the execution history
       :list                       show the source code around current breakpoint
       :list identifier            show the source code for <identifier>
       :list [<module>] <line>     show the source code around line number <line>
       :print [<name> ...]         prints a value without forcing its computation
       :sprint [<name> ...]        simplifed version of :print
       :step                       single-step after stopping at a breakpoint
       :step <expr>                single-step into <expr>
       :steplocal                  single-step within the current top-level binding
       :stepmodule                 single-step restricted to the current module
       :trace                      trace after stopping at a breakpoint
       :trace <expr>               evaluate <expr> with tracing on (see :history)
    
     -- Commands for changing settings:
    
       :set <option> ...           set options
       :seti <option> ...          set options for interactive evaluation only
       :set args <arg> ...         set the arguments returned by System.getArgs
       :set prog <progname>        set the value returned by System.getProgName
       :set prompt <prompt>        set the prompt used in GHCi
       :set editor <cmd>           set the command used for :edit
       :set stop [<n>] <cmd>       set the command to run when a breakpoint is hit
       :unset <option> ...         unset options
    
      Options for ':set' and ':unset':
    
        +m            allow multiline commands
        +r            revert top-level expressions after each evaluation
        +s            print timing/memory stats after each evaluation
        +t            print type after evaluation
        -<flags>      most GHC command line flags can also be set here
                             (eg. -v2, -fglasgow-exts, etc.)
                        for GHCi-specific flags, see User's Guide,
                        Flag reference, Interactive-mode options
    
     -- Commands for displaying information:
    
       :show bindings              show the current bindings made at the prompt
       :show breaks                show the active breakpoints
       :show context               show the breakpoint context
       :show imports               show the current imports
       :show modules               show the currently loaded modules
       :show packages              show the currently active package flags
       :show language              show the currently active language flags
       :show <setting>             show value of <setting>, which is one of
                                      [args, prog, prompt, editor, stop]
       :showi language             show language flags for interactive evaluation
    

      

    Prelude> :show modules
    Prelude> :show context
    
    Prelude> :show bindings
    names :: [Char] = "Daniel King"
    nums :: [Integer] = 1 : 2 : 3 : 4 : 5 : ....
    it :: [Integer] = 2 : 4 : 6 : 8 : 10 : ....
    Prelude> :show imports
    import Prelude -- implicit
    Prelude> :show packages
    active package flags: none
    Prelude> :show languages
    base language is: Haskell2010
    with the following modifiers:
      -XNoDatatypeContexts
      -XNondecreasingIndentation
    

      

    Prelude> foldl ((+)) 0 [1..100]
    5050
    

      

    Prelude> :type map
    map :: (a -> b) -> [a] -> [b]
    Prelude> :type filter
    filter :: (a -> Bool) -> [a] -> [a]
    Prelude> :type foldr
    foldr :: (a -> b -> b) -> b -> [a] -> b
    Prelude> :type foldl
    foldl :: (a -> b -> a) -> a -> [b] -> a
    

      

      

    Prelude> filter ((>) 50) nums
    [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49]
    

      

    Prelude> :type foldr
    foldr :: (a -> b -> b) -> b -> [a] -> b
    Prelude> foldr (:) "King" ['D','a','n','i','e','l', ' ']
    "Daniel King"
    

      

    但是用foldl就不行。

    使用子模块功能

    Prelude> map Data.Char.isDigit ((++) ['0'..'9'] ['a'..'z'])
    [True,True,True,True,True,True,True,True,True,True,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False]
    Prelude> map Data.Char.isDigit (concat [['0'..'9'],['a'..'z']])
    [True,True,True,True,True,True,True,True,True,True,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False,False]
    

      

    另外,(++) 与concat的功能不相同,它们的原型也不相同,因此在使用一个函数之前,一定要明确这个函数的原型。

  • 相关阅读:
    可空类型转换为不可空的普通类型
    如何使用AspNetPager分页控件和ObjectDataSource控件进行分页
    TFS映射后丢失引用的问题
    (很好用)JS时间控件实现日期的多选
    取两个日期之间的非工作日的天数(指的是周六、周日)
    在日期格式化的时候提示错误:Tostring没有采用一个参数的重载
    Linq返回的集合类型不是已有的表格类型时的写法(谨记:列表的时候用)
    系统缓存全解析6:数据库缓存依赖
    实现文本框动态限制字数的实现(好方法)
    实现GridView内容循环滚动
  • 原文地址:https://www.cnblogs.com/long123king/p/3838196.html
Copyright © 2011-2022 走看看