首页
学习
活动
专区
圈层
工具
发布

铁定不纯的IO_Haskell笔记5

写在前面 一直有个疑惑,Haskell号称纯函数式语言,那么铁定不纯的场景(肯定有副作用,或者操作本身就是副作用)如何解决?...Haskell的做法其实类似于React的componentDidMount()等组件生命周期函数,React建议(道德约束)保持render()是纯函数,带有副作用的操作挪到componentDidMount...Haskell提供了do语句块,也是用来隔离不纯的部分的 一.I/O action 先看个函数类型: > :t print print :: Show a => a -> IO () print函数接受一个...' (x:xs) = do v <- x others <- (sequence' xs) return (v : others) 作用是把I/O List中所有I/O结果收集起来,形成List,...,mapM第一个参数是输入a输出IO b的函数,第二个参数是[a],返回IO [b],返回值类型与sequence一致。

1.9K30

Haskell 自定义type与typeclass

解释下:class Eq a where代表我们定义了一个typeclass叫做Eq,a是一个类型变量,他代表任何我们在定义instance时的类型,接下来我们定义了几个函数,不一定要实现函数但一定要写出函数的类型声明...所以输入 :info Num 会告诉你这个 typeclass 定义了哪些函数,还有哪些类型属于这个 typeclass。:info 也可以查找类型跟类型构造器的信息。...他会显示 Maybe 所属的所有 typeclass。:info 也能告诉函数的型别宣告。...从上面我们可以看到fmap接收一个从a类型映射到b类型的函数和一个装有a类型值的functor,返回一个装有b类型值的functor 看下学list时学到的map函数: Prelude> :t map...这有点像函数,也是接收一个值作为参数并回传另一个值。对于类型如何被套用到泛型上,我们看下正式的定义。 像是3,"abc"或者是takeWhile的值都有自己的类型(函数也是值的一种)。

58810
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    newtype_Haskell笔记8

    一.ZipList与List 在List场景,xs ys表示从左侧xs中取出函数作用于右侧ys中的每一项,有两种实现方式: 笛卡尔积 拉链式的一一结对 分别对应[]和ZipList,例如: import...(ThatType),把原类型(ThisType)包起来,提供不同的实现 二者只是简单的依赖,并没有继承关系,所以通过newtype创建的类型并不自动具有原类型的所有方法(也不会自动获得原类型所实现的.../增强 语法要求 从语法作用来看,newtype与data一样,都用来创建新类型,但newtype限制更多: data can only be replaced with newtype if the...除此之外,就与data关键字没什么区别了 P.S.关于值构造器与参数,见类型_Haskell笔记3 三.对比type和data 关键字 作用 应用场景 data 定义自己的(数据)类型 想要定义完全新的类型...),例如: > head [1, undefined, 3, undefined, undefined] 1 > let (a, _) = (1, undefined) in a + 1 2 特殊地,函数调用时的模式匹配本身是需要计算的

    1K30

    基础语法_Haskell笔记1

    非函数式思维:通过命令告诉电脑要做什么,比如求和是通过循环结构遍历所有的数,相加并记录其和 函数式思维:通过函数来描述出问题是什么,比如求和是把第一个数与其余树的和相加 P.S.关于思维模式的差异,请查看一场函数式思维模式的洗礼...即函数仅用来求值,没有副作用(不会影响外部状态),相同输入总能得到相同的输出 惰性求值:真正需要值的时候才现算,所以此时的一连串计算(函数调用)只是作用于输入数据的一系列变换公式,具体来看就是array.map...(不知道要定义的变量/函数列表结束了没) 子句中声明的变量和函数的作用域是当前函数及其guard,且不包括同名函数的其它模式 子句中可以用模式匹配 允许嵌套使用,辅助函数也可以在自己的where子句中声明需要的变量和辅助函数...带上的话,仅作用于当前条件 复杂一点的,比如求1到100的所有素数: isPrime n = null [ x | x <- [2..n-1], n `mod` x == 0 ] [ x | x 类型元组也可以比较 复杂一点的例子,求所有三边长度皆为整数且小于等于10,周长为24的直角三角形: [ (a, b, c) | c <- [1..10], b <- [1..c], a <- [

    2.8K30

    模块_Haskell笔记2

    一.引用 引用模块的语法格式为: -- 把模块中所有函数加入全局命名空间 import -- 部分引用 import (fn1, fn2) -- 引入数据类型及其值构造器..., right :: Tree a} | Leaf a 只暴露出数据结构Tree及其构造器Branch和Leaf,也可以通过..暴露出所有值构造器: module MyModule (Tree(..))..., replicate等函数参数或返回值都有要求Int类型,不够通用,因此提供了类型更通用的对应版本: genericLength :: Num i => [a] -> i genericTake ::...所以 (==) `on` compare `on` 都是非常棒的惯用套路 P.S.可以通过:browse 命令查看模块中的所有函数及数据类型定义的类型声明 Data.Char String...key Map.keys :: Map.Map k a -> [k] -- 取所有value Map.elems :: Map.Map k a -> [a] 查找: -- 按key查找 Map.lookup

    2.2K30

    深入理解JavaScript作用域

    总结:变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量,然后在运行时引擎就会会作用域中查找该变量,如果能够找到就对它赋值。...RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError 异常。...对象的属性拥有全局作用域 函数作用域 函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。...局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的。 每一段 JavaScript 代码都有一个与之关联的作用域链(scope chain)。这个作用域链是一个对象列表或者链表。...函数的作用域气泡开始找,引擎在这里无法找到 a,因此就会去上一级到所嵌套的 foo(...)的作用域中继续查找。在这里找到了a,因此就使用了这个引用。

    92630

    从惰性IO说起_Haskell笔记6

    数值、字符、布尔类型等都可以有随机值,种子则需要通过特殊的mkStdGen :: Int -> StdGen函数生成,例如: > random (mkStdGen 7) :: (Int, StdGen)...通过类型声明来告知random函数期望返回的随机值类型,不妨换个别的: > random (mkStdGen 7) :: (Bool, StdGen) (True,320112 40692) > random...,编译器能够推断出random $ mkStdGen i所需类型是(Bool, StdGen) 这下有点(伪)随机的意思了,因为random是个纯函数,所以只能通过换种子参数来得到不同的返回值 实际上有更简单的方式...,返回同类型的I/O Action。...’ 如果不清楚具体异常类别(这个是确实不清楚异常类型,查源码都猜不出来),或者希望捕获所有类型的异常,可以用SomeException: > first <- try $ evaluate $ head

    2.8K30

    作用域和闭包

    因此,在当前作用域中无法找到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到该变量,或抵达最外层的作用域(也就是全局作用域)为止。...当抵达最外层的全局作用域时,无论找到还是没找到,查找过程都会停止。 # 异常 如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError 异常。...如果 RHS 查询找到了一个变量,但是尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或着引用 null 或 undefined 类型的值中的属性,那么引擎会抛出另外一种类型的异常...这个原则可以延伸到如何选择作用域来包含变量和函数。如果所有变量和函数都在全局作用域中,当然可以在所有的内部嵌套作用域中访问到它们。...这个对象被用作库的命名空间 ,所有需要暴露给外界的功能都会成为这个对象(命名空间)的属性,而不是将自己的标识符暴漏在顶级的词法作用域中。

    1.3K20

    深入理解JavaScript闭包:原理、实践和优化

    在JavaScript中,每个函数都有一个作用域链,它是一个包含当前函数及其所有父级作用域的列表。...当函数执行时,它会首先在其自身的作用域中查找变量,如果没有找到,则会沿着作用域链向上查找,直到找到变量或者到达全局作用域。2. 闭包的定义闭包是指一个函数与其外部作用域中的变量组成的组合。...当一个函数被定义在一个外部函数的作用域中时,这个函数可以访问其外部作用域中的变量,即使外部函数已经返回。这种特性使得闭包能够保留其外部作用域的状态,从而实现一些高级功能。3....闭包的形成要形成闭包,需要满足以下条件:函数被定义在外部函数的作用域中。函数引用了其外部作用域中的变量。外部函数没有将函数返回给调用者。只有满足这三个条件,才能形成一个闭包。二、闭包的实践1....当点击按钮时,handleClick函数会被执行。由于handleClick函数是在外部函数的作用域中定义的,因此它可以访问外部作用域中的变量,如button。

    1.8K51

    智能合约模糊测试器性能优化实战

    堆叠的条形表示函数调用关系(颜色随机分配以增强美观性和可读性)。对样本输入运行Echidna生成的分析结果主要显示了预期中的常规函数:运行智能合约的函数、生成输入的函数等。...但引起我注意的是一个名为getBytecodeMetadata的函数,它会扫描合约字节码并查找包含合约元数据(名称、源文件、许可证等)的段落。...修复涉及Haskell的State数据类型,该类型用于更方便(且更简洁)地编写传递状态变量的函数。修复方案主要是避免在特定函数中使用State数据类型,改为手动传递状态变量。...假设有以下使用State数据类型对5000万到1的所有数字进行状态简单更改的代码:import Control.Monad.State.StrictstateChange :: Int -> Int -...这得益于Haskell编译器优化(我使用-O2标志编译:ghc -O2 file.hs; ./file,或使用ghc -O2 -prof file.hs; .

    25810

    JavaScript 面试要点:作用域和闭包

    (a + b); } var b = 2021; foo(1); // 2022 在当前的作用域中找不到某个变量时,引擎就会在外层嵌套的作用域中继续查找,直到找到 或 到达最外层作用域(全局作用域)...# 异常 如果 RHS 查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出 ReferenceError 异常。...如果 RHS 查询找到了一个变量,但是尝试对这个变量的值进行不合理的操作,比如试图对一个非函数类型的值进行函数调用,或着引用 null 或 undefined 类型的值中的属性,那么引擎会抛出另外一种类型的异常...编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来。 包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。...; 本质上无论何时何地 ,如果将函数(访问它们各自的词法作用域)当作第一级的值类型并到处传递,你就会看到闭包在这些函数中的应用。

    71020

    Python全网最全基础课程笔记(十三)——作用域,跟着思维导图和图文来学习,爆肝2w字,无数代码案例!

    作用域的分类 Python中的作用域主要分为四种类型,这些类型按照从内到外的顺序排列: 局部作用域(Local Scope):这是最直接的作用域,它包含了函数内部定义的变量。...Global(全局作用域):如果嵌套作用域中也没有找到,Python会在全局作用域中查找变量。 Built-in(内置作用域):最后,Python会在内置作用域中查找变量。...全局作用域(Global) Python中的全局作用域(Global Scope)是变量和函数定义的一个最外层作用域,它跨越了整个程序的运行,是所有局部作用域(如函数内部的作用域)的父作用域。...全局作用域中的变量和函数在整个程序中都是可访问的,只要它们没有被局部作用域中的同名变量或函数所遮蔽(shadowing)。 定义全局变量 在Python中,全局变量是在所有函数外部定义的变量。...builtins Python的builtins模块是一个特殊的模块,它包含了Python解释器提供的所有内置函数、异常、以及其他一些内置标识符。

    72200

    第 18 章 用于大型程序的工具

    namespace nsp { // 相关声明 } 只要能出现在全局作用域中的声明就能置于命名空间内,主要包括:类、变量(及其初始化操作)、函数(及其定义)、模板和其他命名空间。...} 全局作用域中定义的名字(即在所有类、函数及命名空间之外定义的名字),也就是定义在全局命名空间中。...**using指示**一次性注入某个命名空间的所有名字,using指示可以出现在全局作用域、局部作用域和命名空间作用域中,但是不能出现在类的作用域中。...这是因为,当编译器发现对 operator>>的调用时,先在当前作用域中寻找合适的函数,接着查找输出语句的外层作用域。...,而非一个特定的函数,该函数的所有版本都被引入到当前作用域中。

    1.2K20

    第 18 章 用于大型程序的工具

    namespace nsp { // 相关声明 } 只要能出现在全局作用域中的声明就能置于命名空间内,主要包括:类、变量(及其初始化操作)、函数(及其定义)、模板和其他命名空间。...} 全局作用域中定义的名字(即在所有类、函数及命名空间之外定义的名字),也就是定义在全局命名空间中。...**using指示**一次性注入某个命名空间的所有名字,using指示可以出现在全局作用域、局部作用域和命名空间作用域中,但是不能出现在类的作用域中。...这是因为,当编译器发现对 operator>>的调用时,先在当前作用域中寻找合适的函数,接着查找输出语句的外层作用域。...,而非一个特定的函数,该函数的所有版本都被引入到当前作用域中。

    1.3K50

    热爱函数式的你,句句纯正的 Haskell【类型篇】

    调试 目前 Haskell 的主要编译器是 GHC,下载地址,你可以创建 .hs 文件,用 Notepad++ 打开。 GHCi 是 GHC 的一部分,可以解析、调试 Haskell 程序。...&&False not True Char 字符型,与其它语言一致 Prelude> :t "str" "str" :: [Char] Int 有符号整数,它的范围与操作系统和 GHC...函数类型是本篇的重中之重,前面的可以随意看看,但是从此节开始请务必细究。 函数可以理解为从参数到结果的一个映射,比如T1 -> T2。...每个类型类下面都写了一些该类型类中预定义的函数,我们可以接着打印输出体验: // fromInteger 是 Num 类型类下的函数,可以将一个一个的整数转为一个重载的数类型 a Prelude> :t...强类型:可以帮助我们检查错误、对程序进行抽象(函数式编程关键)、具有文档说明作用。

    1.9K30

    理解 JavaScript 中的作用域

    本文中,我们将会详细分析 JavaScript 的不同类型的作用域,以及为了写出更好的代码,介绍它们是如何工作的。 作用域的简单定义是编译器需要变量和函数时去查找它们的地方。听起来很容易对吗?...函数bar的参数wow也是在函数作用域中声明的。实际上,所有函数参数都是在函数作用域中隐式声明的,这就是第9行的console.log(wow)会输出zoom而不是wow的原因。...我们看一下第8行代码console.log(foo);,解释器在执行这行代码之前需要找到变量foo的声明。它再次需要首先在此刻的当前作用域(也即函数bar的作用域)而不是全局作用域中查找。...foo是在这个函数的作用域中声明的吗?并不是。那么,它就会继续向上查找父作用域,函数的外层作用域是全局作用域。那么foo是在这个作用域声明的吗?是的,因此解释器就找到并正确执行该函数。...函数作用域 正如我们在词法作用域中看到的,解释器在当前作用域声明变量,也为这函数中声明的某变量会在函数作用域当中。这种作用域限制于函数本身及其内部定义的其他函数。

    1.4K10

    还担心面试官问闭包?

    闭包是纯函数编程语言的一个特性,因为他大大简化复杂的操作,所以很容易在一些JavaScript库以及其他高级代码中找到闭包的使用。 一言以蔽之,闭包,你就得掌握。...引擎无法在这一层作用域中找到变量a,因此引擎会去上一级嵌套作用域foo(...)中查找,如果找到了,则即使用。 如果a,c 都存在作用域bar(...)...,foo(...)作用域中,console.log(...)即不需要到foo的外部作用域中去查找变量。 无论函数在哪里被调用,且无论他们如何被调用,他的词法作用域都只由函数被声明的位置决定的。...总之,从上面的代码中,我们可以看到闭包的有趣的三个概念 内部函数的参数包含在闭包中 作用域之外的所有变量、即便是函数声明之后的那些声明,也都包含在闭包中....在经典的for循环中使用闭包 ? 如上for循环,大家都知道输出6,毕竟这个作用域中,我们只有一个i,所有的回调函数都是在这个for循环结束以后才执行的。

    61410

    还担心面试官问闭包?

    闭包是纯函数编程语言的一个特性,因为他大大简化复杂的操作,所以很容易在一些JavaScript库以及其他高级代码中找到闭包的使用。 一言以蔽之,闭包,你就得掌握。...引擎无法在这一层作用域中找到变量a,因此引擎会去上一级嵌套作用域foo(...)中查找,如果找到了,则即使用。 如果a,c 都存在作用域bar(...)...,foo(...)作用域中,console.log(...)即不需要到foo的外部作用域中去查找变量。 无论函数在哪里被调用,且无论他们如何被调用,他的词法作用域都只由函数被声明的位置决定的。...总之,从上面的代码中,我们可以看到闭包的有趣的三个概念 内部函数的参数包含在闭包中 作用域之外的所有变量、即便是函数声明之后的那些声明,也都包含在闭包中....在经典的for循环中使用闭包 ? 如上for循环,大家都知道输出6,毕竟这个作用域中,我们只有一个i,所有的回调函数都是在这个for循环结束以后才执行的。

    61320

    《你不知道的JavaScript》-- 作用域(笔记)

    3)作用域 负责收集并维护由所有声明的标识符/变量组成的一系列查询,并实施一套非常严格的规则,确定当前执行的代码对这些标识符的访问权限。 4)引擎进行变量查询的类型 LHS查询:赋值操作的目标是谁。...变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量(如果之前没有声明过),然后在运行时引擎会在作用域中查找该变量,如果能够找到就会对它赋值,否则抛出异常。...,全局作用域中就会创建一个具有该名称的变量,并将其返还给引擎; 3)“严格模式”下如果LHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎也会抛出ReferenceError异常; 4)ReferenceError...这个原则是指在软件设计中,应该最小限度地暴露必要内容,而将其他内容都“隐藏”起来,比如某个模块或对象的API设计。这个原则可以延伸到如何选择作用域来包含变量和函数。...这些库通常会在全局作用域中声明一个名字足够独特的变量,通常是一个对象,这个对象被用作库的命名空间,所有需要暴露给外界的功能都会成为这个对象(命名空间)的属性,而不是将自己的标识符暴露在顶级的词法作用域中

    90320
    领券