首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

铁定不纯IO_Haskell笔记5

写在前面 一直有个疑惑,Haskell号称纯函数式语言,那么铁定不纯场景(肯定有副作用,或者操作本身就是副作用)如何解决?...Haskell做法其实类似于ReactcomponentDidMount()等组件生命周期函数,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.3K30

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值都有自己类型函数也是值一种)。

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

    模块_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

    1.7K30

    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 特殊地,函数调用时模式匹配本身是需要计算

    61430

    基础语法_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 <- [

    1.9K30

    深入理解JavaScript作用

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

    70330

    作用域和闭包

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

    71120

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

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

    84151

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

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

    43820

    从惰性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.3K30

    热爱函数你,句句纯正 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...强类型:可以帮助我们检查错误、对程序进行抽象(函数式编程关键)、具有文档说明作用

    95330

    第 18 章 用于大型程序工具

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

    92720

    第 18 章 用于大型程序工具

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

    98650

    理解 JavaScript 中作用

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

    92910

    还担心面试官问闭包?

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

    46410

    还担心面试官问闭包?

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

    40520

    泛型和元编程模型:Java, Go, Rust, Swift, D等

    单态化是针对我们要处理不同类型数据,多次复制代码。这样每份代码都直接使用对应数据结构和函数,而不需要任何动态查找。...这些表通过在固定偏移量处索引某些指针,让通用代码以同样方式为每个类型查找特定类型函数指针。 译者注,图示如下: ?...这种方式虽然被Haskell类型类使用,但GHCGHC是Haskell编译器)通过内联和特殊化,也可以做单态化优化。...这样一来,Swift就可以在没有单态化情况下实现泛型,也不需要把所有类型都使用统一表达。虽然仍然存在所有动态查找成本,然而也节省了分配内存、内存和缓存不连贯成本。...Terra是Lua一种方言,它允许你构建类似C语言低级函数,然后使用Lua API以及引用和拼接原语言在元级来操作它们。

    3K30

    《你不知道js(上卷)》笔记1(基础知识和闭包)

    在当前作用域中无法找到某个变量时,引擎就会在外层嵌套(上一级)作用域中继续查找,直到找到该变量, 或抵达最外层作用域(也就是全局作用域)为止。...函数作用是指,属于这个函数全部变量都可以在整个函数范围内(包括嵌套作用域中)使用及复用。...利用作用规则强制所有标识符都不能注入到共享作用域中,而是保持在私有、无冲突作用域中,这样可以有效规避掉所有的意外冲突。...函数 bar()词法作用域能够访问foo()内部作用域。然后我们将bar()函数本身当作 一个值类型进行传递。 理解闭包 在foo()执行后,通常会期待foo()整个内部作用域都被销毁。...可以将这个对象类型返回值看作本质上是模块公共 API。 模块模式两个必要条件: 必须有外部封闭函数,该函数必须至少被调用一次。

    44420

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

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

    69120
    领券