ghci> :t pure []
pure [] :: Applicative f => f [a]
Run Code Online (Sandbox Code Playgroud)
ghci> pure []
[]
Run Code Online (Sandbox Code Playgroud)
ghci> :t []
[] :: [a]
Run Code Online (Sandbox Code Playgroud)
ghci> fmap ((:) 2) (pure [])
[2]
Run Code Online (Sandbox Code Playgroud)
ghci> fmap ((:) 2) ([])
[]
Run Code Online (Sandbox Code Playgroud)
我本来以为更换pure[]用[]的fmap ((:) 2) (pure [])会导致同样的结果..谁可以解释的差异吗?
我正在实施一个近似计数算法,其中我们:
使用log(log n)位维护计数器X.
将X初始化为0
当物品到达时,增加X的概率(1/2)由1 X
当流结束时,输出2 X - 1,使E [2 X ] = n + 1
我的实现如下:
import System.Random
type Prob = Double
type Tosses = Int
-- * for sake of simplicity we assume 0 <= p <= 1
tos :: Prob -> StdGen -> (Bool,StdGen)
tos p s = (q <= 100*p, s')
where (q,s') = randomR (1,100) s
toses :: Prob -> Tosses -> StdGen -> [(Bool,StdGen)]
toses _ 0 …Run Code Online (Sandbox Code Playgroud) 我发现自己经常打字,就像我做了一些改变,提交它,然后要么查找我在那里做的事情以确定接下来要做什么,或者确保我没有添加任何意外的提交在将它推到遥控器之前.
不可否认,diff HEAD^ HEAD类型(git diTABHTAB←^ HTAB)足够快,但仍然觉得应该有更好的方法.
如何最简单地查看上次提交中所做的所有更改?
当我第一次阅读严肃的批评时-XUndecidableInstances,我已经完全习惯了它,将其视为仅仅删除了令人讨厌的限制Haskell98必须使编译器更容易实现.
事实上,我遇到了大量需要不可判定实例的应用程序,但没有一处它们实际上导致任何与不可判定性相关的问题.卢克的例子存在问题,原因完全不同
class Group g where
(%) :: g -> g -> g
...
instance Num g => Group g where
...
Run Code Online (Sandbox Code Playgroud)
- 好吧,这显然会被任何适当的实例重叠Group,所以不可判断性是我们最不担心的事情:这实际上是不确定的!
但公平地说,我自己保留了"不可判断的实例可能会让编译器挂起".
当我在CodeGolf.SE上阅读这个挑战时获得它,请求代码无限地挂起编译器.嗯,听起来像是不可判断的实例的工作,对吧?
事实证明我无法让他们这样做.以下编译,至少从GHC-7.10开始:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y
instance C y => C y
main = return ()
Run Code Online (Sandbox Code Playgroud)
我甚至可以使用类方法,它们只会在运行时引起循环:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y where y::y
instance C y => C y …Run Code Online (Sandbox Code Playgroud) 如果A是n × n矩阵而x是维数n的向量,那么可以将xGEMV作为参数传递给x和y参数beta=0,以实现操作x ← A · x?
我对使用C接口的Cublas实现特别感兴趣.
最近我正在阅读一些涉及Haskell的函数式编程书籍.
看来Haskell非常喜欢"模块化程序",例如,
f :: (Integer,Integer) -> Integer
f = sum . map sq . filter . odd . between
Run Code Online (Sandbox Code Playgroud)
即使可以写出相同的功能
f' (m, n) = go m
where go m | m > n = 0
| otherwise = go (m + 1) + if odd m then sq m else 0
Run Code Online (Sandbox Code Playgroud)
"融合法"也很受欢迎并被使用(http://www.cs.ox.ac.uk/ralf.hinze/publications/IFL10.pdf)
我不是OCaml专家,但我会使用fold_left或fold_right尽可能简单高效(例如,无论如何我必须扫描整个列表并且不会停在中间).
但是,在大多数情况下,我将使用"模式匹配"编写显式递归代码.
另外我在github中读了很多OCaml项目,显式递归似乎很常见.
另外,我从未听说过OCaml的融合法.
我的问题是
我已经开始严重依赖haskell的类型系统来避免错误,并且正在寻找是否也可以用来确保(弱?)形式的代码正确性.
我想到的代码正确性的形式如下:
f :: a -> b如果f保证b为任何类型的输入生成类型的输出,则函数是正确的a.对于众所周知的功能头(head:: [a] -> a),这显然是失败的.
我知道类型系统无法保证这种形式的正确性的一种方法是代码使用error(error :: Char -> a).错误函数几乎覆盖了整个类型系统,因此除非明确指出,否则我希望避免使用此函数.
我的问题是双重的:
除了错误之外还有哪些其他函数(或haskell片段)是Haskell类型系统的例外?
更重要的是,有没有一种方法禁止在Haskell模块中使用这些函数?
非常感谢!
当具有以下签名的函数有用时,任何人都可以分享良好的现实生活情况吗?
f (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
我无法真正看到我需要的东西,比如来自Learn-you-a-haskell的教科书示例 [(+),(*)] <*> [1,2] <*> [3,4]
我发现了这些类型的签名:
x :: a b -> Int
x f = 3
y :: a b c -> Int
y f = 3
z :: a b c d -> Int
z f = 3
> x [1] -- 3
> y (1, 2) -- 3
> z (1, 2, 3) -- 3
Run Code Online (Sandbox Code Playgroud)
基本上:
它们是有效的,但我不确定它们的含义以及它们可以用于什么.
它们似乎与类型构造函数上的多类型概念或多态相关,但是基于类型构造函数接受的许多参数强制执行不变量.
我想用模式匹配的递归函数用字符串中的空格替换 \n,但我不知道如何匹配 \ 字符。
这是我的功能:
replace :: String -> String
replace ('\\':'n':xs) = ' ' : replace xs
replace (x:xs) = x : replace xs
replace "" = ""
Run Code Online (Sandbox Code Playgroud)
在('\':'n':xs)反斜杠中会转义单引号并弄乱代码,所以我写('\\':'n':xs)期望第一个 \ 会转义第二个 \ 并匹配字符串中的反斜杠。然而,事实并非如此。
这就是我在 GHCi 中尝试该函数时发生的情况:
*Example> replace "m\nop"
"m\nop"
*Example> replace "m\\nop"
"m op"
Run Code Online (Sandbox Code Playgroud)
如何匹配单个反斜杠?
haskell ×8
algorithm ×1
applicative ×1
blas ×1
c ×1
correctness ×1
cuda ×1
fortran ×1
git ×1
git-diff ×1
ocaml ×1
polymorphism ×1
random ×1
typeclass ×1
types ×1