有些类型具有自扁平化性质,称为幂等性:
https://en.wikipedia.org/wiki/幂等性
幂等性是数学和计算机科学中某些运算的属性,可以多次应用它们,而不会改变初始应用之外的结果。
在 JavaScript/TypeScript 中,我们有Object/Number 对象作为幂等性的实例。
现实世界的用例是在 TypeScript 中使用正确的类型编写自己的 Promise。你永远不可能Promise<Promise<T>>只让Promise<T>承诺自动变平。例如,单子也会发生同样的情况。
console.log(
Number(5) === Number(Number(5))
); // trueRun Code Online (Sandbox Code Playgroud)
简而言之,它通常表达为
发送 = 发送
编辑:事实上,这可能是一个有点令人困惑的概念;因为幂等永远不会有比T更多的结构,以JS数组形式[foo]。另一方面,monad 操作(在 Haskel 词中绑定)是 TTX = TX,但它确实具有类似于[[foo]].
Array.map组成是[[foo]] => [[[foo]]]
Array.flatMap合成图+平面(TTX=TX) 是[[foo]] => [[foo]]
我认为这是 monad,但不是幂等的。令人困惑,是的。
我以某种方式设法编写了函数
const toObject = <A, X>(x: A): A extends T<X> ? A : //...
((X:object)=> {/* ... */})(Object(x)) ;
Run Code Online (Sandbox Code Playgroud)
A extends T<X> ? A : //...在某些函数内部的上下文中工作,但我不知道如何单独编写类型本身,即使使用函数结构,它也非常复杂,我觉得有些事情很错误。
我想知道和写的是 …
基本上,我需要为函数组合定义中缀运算符,翻转g . f方式。
(#) :: (a -> b) -> (b -> c) -> a -> c
(#) = flip (.)
infixl 9 #
Run Code Online (Sandbox Code Playgroud)
在这里,我暂时选择了符号:#,但我不确定这个选择在与其他定义的冲突方面不会有问题。
奇怪的是我在 Haskell 中找不到预定义的中缀运算符列表。
我希望组合运算符尽可能简洁,希望是像 这样的单个字符.,如果可能的话,我想让它成为&。可以吗?
有任何指导或最佳实践教程吗?请指教。
相关问答:
我尝试使用\n Control.Monad.Extra.andM
\nimport Control.Monad.Extra (andM)\nRun Code Online (Sandbox Code Playgroud)\n但有一个错误:
\nCould not find module \xe2\x80\x98Control.Monad.Extra\xe2\x80\x99\nPerhaps you meant\n Control.Monad.Catch (needs flag -package-key exceptions-0.10.4)\n Control.Monad.Error (needs flag -package-key mtl-2.2.2)\n Control.Monad.Except (needs flag -package-key mtl-2.2.2)not found\nRun Code Online (Sandbox Code Playgroud)\n这个错误没有意义。
\n根据
\nhttps://cabal.readthedocs.io/en/3.6/installing-packages.html#installing-packages-from-hackage
\n\n\n3.2.1. 从 Hackage 安装软件包\nCabal 工具还可以一步下载、配置、构建和安装 Hackage 软件包及其所有依赖项。为此,请运行:
\n
$ cabal install [PACKAGE...]\nRun Code Online (Sandbox Code Playgroud)\n\n\n要浏览可用软件包的列表,请访问 Hackage 网站。
\n
这说的是“一步到位”,但根据我的经验,这太复杂了,实际上我不知道如何安装Control.Monad.Extra。
通常,当 Haskeller 想要安装这样的特定库/包时,你该怎么做?似乎没有足够的文件。
\n我花了好几天的时间来构建一个data具有可变值字段的结构Data.Vector.Mutable
我确认Data.Vector.Mutable它的行为符合我的预期;然而,一旦它被纳入一个结构中,就会以某种方式停止工作,这违背了我的期望。
下面是一个演示代码,它仅具有newVal,getVal并setVal针对结构的可变字段值。
newIO是类型为 的数据结构的构造函数newIO :: a -> A a。
module Main where
import Control.Monad.Primitive (PrimMonad (PrimState))
import qualified Data.Vector.Mutable as M
------------------------------------
data A a = A
{ ioVal :: IO (M.MVector (PrimState IO) a)
}
newIO :: a -> A a
newIO = \a -> A (newVal a)
------------------------------
newVal :: a -> IO (M.MVector (PrimState IO) a)
newVal = \a -> do
val …Run Code Online (Sandbox Code Playgroud) 我想使用HList:异构列表。
import Data.HList (HList)至此就完成了库的安装。
现在调查https://bitbucket.org/HList/hlist/src/master/examples/HListExample/并不能帮助我开始编写代码。
我想做的是,
创建一个 hello-world 异构列表,例如H[1, "2"](完全不确定语法)
将异构列表映射到print每个列表。
有没有人熟悉如何使用HList?
类型是什么
let plus:Plus = |x| move |y| x + y;
Run Code Online (Sandbox Code Playgroud)
明显地,
type Plus = fn(isize) -> fn(isize) -> isize;
Run Code Online (Sandbox Code Playgroud)
不会工作,因为最后一部分不是函数指针而是闭包。
我在符号上下文中看到了很多 ST monad 的例子do;然而,由于这不适合我的目的,我尝试在线程之外newSTRef使用ST monad 。modifySTRefdo
该类型是由 VSCode 的 HLS 自动添加的。
\nref :: ST s (STRef s Integer)\nref = newSTRef (1)\n\nx :: ST s ()\nx = modifySTRef ref 2\nRun Code Online (Sandbox Code Playgroud)\n错误:ref在最后一行
Couldn't match expected type \xe2\x80\x98STRef s a0\xe2\x80\x99\n with actual type \xe2\x80\x98ST s0 (STRef s0 Integer)\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n好吧,我当然可以看到错误说类型不匹配,但我不知道如何修复它。
\nST Monad 之外的正确用法是什么do?
编辑:
\n我的目的没有do是
就像提到的那样,do仅仅是一种语法糖,我通常想避免它,以便以更简单的功能方式编写代码。
获取可变对象的目的是为了开发FRP,而ref …
为了在函数上下文中获得顺序计算,在 JavaScript 中,我经常使用
const right = a => b => b;
const f = () => right(console.log("hi"))(true);
console.log(f());Run Code Online (Sandbox Code Playgroud)
这有点类似于do线程,并且实现起来更简单,但仅适用于急切求值的语言,例如 JavaScript。
在 Haskell 中,由于该语言以惰性求值/按需调用的方式工作,因此 的参数a将不会被求值,因为 lambda 表达式体中不需要它。
所以,我想知道什么是简单的智能方法来实现right在惰性求值中起作用的函数。 <- 这是我的第一个问题。
有 Haskell wiki 文章:
根据 Haskell 2010 报告,该
seq原语尽管有其名称,但不需要以某种预定义的顺序评估其参数。对于并行编程,有时需要使用 seq 的变体来进行这样的排序:
虽然我们主要关注实现,但我们的工作对编程模型产生了一些影响:我们确定了对 pseq 和 seq 的需求(第 2.1 节),并且我们隔离了编写并行程序的“策略”方法中的一个重大困难(第 7 节)。对多核 Haskell 的运行时支持;西蒙·马洛、西蒙·佩顿·琼斯和萨特南·辛格。不是两个或多个具有相似目的的相似原语,而是使用其参数的传统评估顺序来扩展现有的 seq 原语 - 首先,然后第二;简单严格控制的角色由具有更合适名称的新原语执行,例如
amid,在没有排序或混乱的严格性中。
和
由于 Haskell 2010 报告没有指定关于其参数的任何计算顺序,因此原语的名称
seq :: a -> b -> b是用词不当。
引入原语 …
我认为joinJavaScript具有Control.Monad相同的功能。Array.flat
https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
然而,这与我的预期相反,实际行为是
f :: Maybe a -> Maybe a
f = \a -> join (Just a) -- works as I expected
f' :: a -> Maybe a
f' = \a -> join (Just a) -- I thought it returns Maybe a
-- Occurs check: cannot construct the infinite type: a ~ Maybe a
-- Expected type: Maybe (Maybe a)
-- Actual type: Maybe a
Run Code Online (Sandbox Code Playgroud)
是否有可用的扁平化功能或任何解决方法?
我想这可能是一个有争议的话题,因为我深入接触了语言设计,而且我知道周围有些人不会喜欢这样,因为他们误解了我否认了他们喜欢的东西的某些优点。
\n为什么 Haskell 需要IO/Actions,即使它是惰性求值?
\n我理解 IO/Actions 机制的价值,如果它是针对 C、JavaScript 或任何其他语言等急于评估的语言,那么它可以保持函数式编程的所谓“纯度”。
\n事实上,我确实IO ()在 Typescript 中模拟/实现了急切的求值,然后我想“好吧,很酷,但是为什么 Haskell 需要这个?”
Haskell 默认情况下是惰性的,因此即使函数也被定义为
\nprint==console.log
在 JavaScript 语法中,在 Haskell 中,因为它是惰性的,print所以除非它连接到main :: IO ().
有什么想法吗?
\n编辑:
\n显然,这个问题源于我的完全误解。
\n在 Haskell 中,它定义为
\nprint==console.log
print :: Show a => a -> IO () -- Defined in \xe2\x80\x98System.IO\xe2\x80\x99
我只是误解了好像定义为
\nprint :: Show a => …
我需要定义一个联合类型,该类型的集合包括
\na -> b 或者 a -> IO b
a -> b || a -> IO b
或者
\na -> b | IO b
foo :: (a -> b | IO b) -> IO (R a) -> IO (R b)
我试过data unionType b = b | IO b,不行。
Not a data constructor: \xe2\x80\x98b\xe2\x80\x99parser\nNo quick fixes available\nRun Code Online (Sandbox Code Playgroud)\n在哈斯克尔可以吗?
\n