据我所知,函子是两个类别之间的映射,例如
中的对象
哪里
和
都是类别。
在Haskell中有Hask,其中对象是Haskell类型,而态射是Haskell函数。但是,Functor类型类有一个函数fmap,它在这些类型之间映射(因此是对象,而不是类别本身):
fmap :: (a -> b) -> f a -> f b
f a和f b都是Hask中的对象。这是否意味着Haskell中的每个Functor实例都是一个函数,如果不是,Functor是否真的表示一个函子?
我在这里错过了什么?类型也在Haskell中吗?
从数学上讲,函数应用的二进制运算是一个内函子/Monad.
pipe :: (a -> b) -> a -> b
pipe = \f -> \a -> f a
(|>) :: a -> (a -> b) -> b
(|>) = flip pipe
infixl 1 |>
它被称为管道操作符,在Haskell中,预定义为
(&) :: a -> (a -> b) -> b
monadTestPipe :: IO ()
monadTestPipe = do
"Monad Laws=====
我已经从理查德·伯德的“使用Haskell的FP入门”开始学习Haskell,但我仍然坚持证明以下几点:
pair (f, g) . h = pair (f . h, g . h)
对的定义如下:
pair :: (a -> b, a -> c) -> a -> (b, c)
pair (f, g) x = (f x, g x)
有人能给我指明正确的方向吗?请记住,我只是刚开始。提前感谢!
目前,我正在与Hutton教授的“Haskell编程”一起学习Haskell,我发现了一些奇怪的东西,可能是类应用实例的定义。
在GHC.Base中,实例Applicative Maybe定义如下:
instance Applicative Maybe where
pure = Just
Just f <*> m = fmap f m
Nothing <*> _m = Nothing
困扰我的是将Nothing <\*> _的值定义为Nothing的行。Nothing是Maybe a类型,操作符<*>实际上需
来自Javascript,我理解Haskell的list类型强制执行同构列表。现在,令我感到惊讶的是,以下不同的函数类型满足了这一要求:
f :: (a -> a) -> a -> a
f g x = g x
g :: (a -> b) -> a -> b
g h x = h x
let xs = [f, g] -- type checks
尽管g比f更广泛地适用
f(\x -> [x]) "foo" -- type error
g(\x -> [x]) "foo" -- type checks
(a -&
Haskell中的函数组合操作符定义为:
(.) :: (b -> c) -> (a -> b) -> a -> c
当我试图在Haskell中创建我自己的函数组合操作符o时,它不起作用,我做错了什么?
o :: a -> (a -> b) -> (b -> c) -> c
g :: Double -> String
g x = show x
h :: Int -> Double
h x = fromIntegral x
f :: Int -> String
f x = o x h g -- ca
Haskell中的免费实现是:
data Free f a =
Pure a
| Free (f (Free f a))
然而,Scalaz中的实现是:
sealed abstract class Free[S[_], A]
private case class Return[S[_], A](a: A) extends Free[S, A]
private case class Suspend[S[_], A](a: S[A]) extends Free[S, A]
private case class Gosub[S[_], B, C](a: Free[S, C], f: C =>
考虑以下有效的Haskell代码
module Main where
main :: IO ()
main = do
let x = f
print x
f :: Maybe (Int, Int)
f =
Just 3 >>= (\a ->
Just 5 >>= (\b ->
return (a, b)))
其中,函数f可以用下面这样的do-表示法进行等效重写
f :: Maybe (Int, Int)
f = do
a <- Just 3
b <- Just 5
return (a, b)
让我烦
在haskell我可以用
sortBy (comparing snd)
按元组中的第二个值排序。
是否有测试等效性的等效函数?我想出了这个,但是标准库里可能有什么东西。
equalsBy :: Eq b => (a -> b) -> a -> a -> Bool
equalsBy f x y = f x == f y
最终目标是按第二个值对一组对进行分组。有了这个我就能做到
groupBy (equalsBy snd) pairs
而不是
groupBy (\x y -> (snd x) == (snd y)) pairs
在“Haskell中的编程”一书中,foldr的定义是:
foldr :: (a -> b ->b) -> b -> [a] -> b
foldr f v [] = v
foldr f v (x:xs) = f x (foldr f v xs)
我不能很好地理解f。
因为f被应用于[a],所以(a -> b -> b)中的参数a是显而易见的。参数v有b类型,但是(a -> b -> b)和(a -> b -> b) -> b -> a -> b中的最后一个b是奇怪的。
这是否意味着函数f和foldr的结果具有b
我是Haskell的新手,在实践中,我一直在使用map和foldl实现一系列函数(如foldr、length等)。现在我想搬到树上去!
我的树数据结构:
data Tree a = Node a [Tree a] deriving (Show)
我写了一个Haskell函数来折叠树木:
treeFold :: (b->a->b) -> b -> Tree a -> b
treeFold f s (Node a []) = f s a
treeFold f s (Node a xs) = foldl f (f s a) (dFSList xs)
其中dFSList
我有两个我认为是等价的类型类和实例定义的实现。PureScript版本构建时没有错误,但是Haskell版本在错误Un-determined variables: e, f中失败。
我能在Haskell做这件事吗?
Haskell:
class Foo a b c | a b -> c where
newtype Bar a b = Bar (a, b)
instance (Foo a c e, Foo b d f) => Foo (Bar a b) (Bar c d) (Bar e f) where
PureScript:
class Foo a b c | a b ->
我正在尝试使用foldl创建foldr (这是学习haskell的一个很好的练习,而另一个问题的答案似乎很复杂)。
我的解决办法是:
myFoldl :: (b -> a -> b) -> [a] -> (b -> b)
myFoldl f = foldr op z
where
z = []
op x xs b = myFoldl f xs (f b x)
但不起作用。我说错了:
• Couldn't match type ‘a -> b’ with ‘[a]’
Expected type: b -> (a ->
我很难理解Haskell中类型签名背后的推理。
1)由于->被认为是正确的结合,它是否意味着可以用类似的方式来理解它,例如4^(2^(3^2))?
2)使用简单函数的类型签名来表达我的疑虑(为了解释我理解它的方式,我将使用a、b、c而不是Num a => a或Int的):
myAdd :: a -> b -> c
myAdd x y = x+y
这意味着函数接受参数a,并返回接受b并最终返回c的函数。
但它可以改写为:
myAdd :: (a->(b->c))
由于大多数学习材料指出,c在我们的例子中是函数myAdd的结果,为什么用括号表示第一个‘操作’是b
.NET框架中的LINQ库有一个非常有用的函数,叫做,我一直在使用这个函数。它在Haskell中的类型如下所示
Ord b => (a-> b) -> [a] -> [(b, [a])]
它的目的是基于给定的分类函数f将物品分类到桶中,每个桶包含相似的物品,即(b, l),使得对于l中的任何物品x,f x == b。
它在日志中的性能是O(N),因为它使用了哈希表,但在Haskell中我可以接受O(N* .NET (N))。
我在标准的Haskell库中找不到任何类似的东西。此外,我在标准函数方面的实现有些笨重:
myGroupBy :: Ord k => (a
我是哈斯克尔的初学者。
根据我的学校教材,在函数定义中使用的惯例实际上如下
function_name arguments_separated_by_spaces = code_to_do
例:
f a b c = a * b +c
作为一名数学学生,我习惯于使用以下功能
function_name(arguments_separated_by_commas) = code_to_do
例:
f(a,b,c) = a * b + c
它在Haskell工作。
我怀疑它是否在所有情况下都有效?
我的意思是,在Haskell函数定义中,我也可以使用传统的数学惯例吗?
如果错误,在哪些具体情况下公约
Haskell中的列表可能如下所示:
data List a = Nil | Cons a (List a)
一种类型理论解释是:
λα.μβ.1+αβ
将列表类型编码为函子的不动点。在Haskell,可以代表这一点:
data Fix f = In (f (Fix f))
data ListF a b = Nil | Cons a b
type List a = Fix (ListF a)
我对早期的μ绑定器的范围很好奇。在外部作用域中绑定的名称在内部作用域中是否仍然可用?例如,下面是一个有效的表达式:
μγ.1+(μβ.1+γβ)γ
...perhaps --它与:
μβ.μγ.1+
Haskell的bind运算符(>>=)的类型签名:
m a -> (a -> m b) -> m b
F#正向管道操作符(|>)的类型签名:
'a -> ('a -> 'b) -> 'b
他们看起来很像。考虑到F#的不纯性质,|>在Haskell中的等价算子是>>=。
例如:
哈斯克尔:
getLine >>= putStrLn
F#:
stdin.ReadLine() |> stdout.Write
我现在在研究haskell。但我在和“类型”做斗争。
例如,,f函数的类型是
f g (x,y)= g x y
(a -> b -> c) -> (a, b) -> c
类型的Haskell函数h
h f g x y = f (g x y) x
(a -> b -> c) -> (b -> d -> a) -> b -> d -> c
我如何理解如何猜测函数的类型?
作为一名功能良好的Javascript开发人员,我对Haskell的理解非常模糊,我真的很难理解像monad这样的Haskell成语。当我查看函数实例的>>=时
(>>=) :: (r -> a) -> (a -> (r -> b)) -> r -> b
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
// Javascript:
及其在Javascript中的应用
const bind = f => g => x =>
从Haskell开始,我经常遇到类型方面的问题(以及GHC的错误消息不太有用)。我定义了以下功能:
ghci> let f x = floor x == x
ghci> :t f
f :: (Integral a, RealFrac a) => a -> Bool
这是成功的,但调用接缝是困难的:
ghci> let a = 1.1
ghci> f a
<interactive>:296:1:
No instance for (Integral Double) arising from a use of `f'
Poss
我开始学习函数式编程(,OCaml),但我不理解关于fp的一个重要主题:签名(我不确定它是否是一个合适的名称)。当我键入某些内容并使用ocaml进行编译时,例如:
# let inc x = x + 1 ;;
val inc : int -> int = <fun>
这是微不足道的,但我不知道,为什么:
let something f g a b = f a (g a b)
给出一个输出:
val something : (’a -> ’b -> ’c) -> (’a -> ’d -> ’b) -> ’a -> ’d -> ’c
让我们假设我有一个类型
data F a = A a | B
我像这样实现函数f :: F a -> F a -> F a:
f (A x) B = A x
f B (A _) = B
f (A _) (A x) = A x
然而,没有f B B这样的东西在逻辑上是不可能的,所以我想:
f B B = GENERATE_HASKELL_COMPILE_ERROR
当然不起作用。省略定义或使用f B B = undefined不是解决方案,因为它会生成运行时异常。我想得到编译时类型错误。
编译器拥有所有的信息,它应该能够推断出我犯了一个逻辑错误。如果我声明let z = f (f B
是否可以在Haskell98或扩展中编写以下函数f
f :: (a -> b) -> (b -> a) -> c -> d
where (c,d) :: (a,b) || (c,d) :: (b,a)
我正在尝试创建一些泛型函数,以便在任意两种类型的a和b之间进行转换,但两者都有点任意性很难做到。但是,第一个参数a ->b立即设置了它们,所以我希望这是可能的。任何指导都很感激..。
谢谢!
编辑
在我看来,我的问题归结为haskell的类型系统是否支持or关键字.我的函数的直观签名是:f :: (a->b) -> (b->a) ->
在阅读Haskell书时,我遇到了下面的示例,在这个示例的第4行中,f a的结果存储在CountMe的b参数中,而n'则是初始绑定定义中n值的副本。我以前没有见过这种类型的let子句,我是正确的,我的假设以上,还是正在发生其他事情。另外,这是否是let子句的一种常见用法,似乎相当混乱?
instance Monad CountMe where
return = pure
CountMe n a >>= f =
let CountMe n' b = f a
in CountMe (n + n') b
我正在从赫顿的书“Haskell中的编程”(第二版)中学习Haskell。开始的时候。7 .“高阶函数”,函数“两次”的定义为:
twice :: (a -> a) -> a -> a
twice f x = f (f x)
然后给出了几个使用示例,例如:
> twice reverse [1,2,3]
[1,2,3]
然后作者说,“将一个(有限)列表反转两次没有任何效果的事实被方程二次反向=id.”当我开始写作时:
GHCi, version 8.4.4: http://www.haskell.org/ghc/ :? for help
Prelude> :ty
在创建更通用的Monads的过程中,我一直在通过Haskell中的一些范畴理论来构建自己的方法。
在我可以进入下一步之前,我需要能够使用自然转换。
现在,常规Functor上的自然转换已经足够简单了,它们只是一些函数
trans :: forall a . F a -> G a
(其中F和G是Functors),附加限制为
fmap f . trans = trans . fmap f
等同于交换图:
然而,当我继续讨论更多的分类函数式时
class
( Category cat1
, Category cat2
)
=> Functor cat1 c
我最近才开始学haskell。在函数定义中,我对声明函数类型有些混淆。例如,如果我们想要定义一个foldr函数:
foldr :: (a->b->b)->b->[a]->b
foldr f v [] = v
foldr f v (x:xs) = f x (foldr f v xs)
因此,foldr (+) 0 1,2,3,4 = 1,2,3,4 = 10。
我的问题是:我能不能把它改为:
foldr :: (a->a->a)->a->[a]->a
OR:
foldr :: (a->b->c)->x->[y]
在Haskell中,你可以很容易地用几行代码定义一个复杂的结构。一个小的例子是:
data A = B Float
| C Int
| D [D]
data D = E [A]
| F Int
要将其转换为面向对象的语言,您是否必须为A-F创建一个类,然后使用继承来定义这个相同的结构?还是有其他的速记?
我有一个任务,数据类型是在Haskell中指定的,我(错误地)选择了C#,但现在回去已经太晚了。
因此,这是行不通的:
take 50 iterate (* 2) 1
因为它需要在“取”的第二个参数中插入。我的问题是为什么。
Haskell正确地看到了这几种类型的差异:
Couldn't match expected type `[a0]'
with actual type (a1 -> a1) -> a1 -> [a1]'
我的问题是:
1) haskell似乎首先尝试在迭代函数之前解析取50函数。为什么haskell要这么做?当在数学中,如果你有f,t,w,u(x),你首先评估u (x),然后再做其他事情。为什么在这种
我知道在Haskell中,有一个很棒的特性叫做函数组合,这样我们就可以使我们的Haskell代码变得更加简洁,比如:
使用(f . g) x而不是f (g x),
使用foo x $ bar y z而不是foo x (bar y z)
但是,我们是否可以将函数组合用于foo (bar x) (bar y)?
让我们看看这些函数的类型,例如:
:t traverse
traverse
:: (Applicative f, Traversable t) => (a -> f b) -> t a -> f (t b)
:t id
id :: a -> a
它们没有具体类型,但是有泛型参数:a、f、b、t (如果它们调用了泛型参数,请更正我)。
如果我用这种方式把id和traverse组合在一起,
:t traverse id [Just 1, Just 2, Nothing]
traverse id [Just 1, Just 2, Nothing] :: Num
例如
let When true d = d
let foo = () |> When false
所以我有不喜欢的副作用,因为它是错误的:MatchFailureException
我知道我在这里有很好的副作用:let foo = if false then ()
但是警告Incomplete pattern matches on this expression.告诉我,我可以添加我需要的东西。我只是不知道怎么做或者是否可能?否则为什么我甚至可以用值作为参数呢?
顺便说一句:我知道我可以写When b d = if b then d else (),但问题比较普遍。
在haskell中
我开始查看一些Haskell代码,发现:
foo :: ([a] -> [b]) -> [a] -> [(a, b)]
let foo = (<*>) zip
我不明白这是如何工作的,ap需要一个f (a -> b) -> f a,但是zip的类型是[a] -> [b] -> ([a, b])。我知道f a -> f b可以匹配[a] -> [b],但不能匹配f (a -> b)。
如何确定Haskell类型在给定平台上是否具有等效强制实例?
我刚刚在GHC7.8中听说了,这似乎很棒。在这种情况下,我想解决我的具体问题的一个同样好的问题是:是否有一种方法来询问GHC关于哪一对类型的a、b有Coercible a b实例(例如,在当前平台上)?
在我看来,要使在编译器和平台无关的程序中很有用,人们需要知道--最好是在编译时--但在编写代码时也可能明确地知道给定的Coercible a b实例是否存在于给定的平台上,并以其他方式使用更慢的非noop回退(我猜是通过CPP )。
后续问题:为GHC提供一个功能是否合理?
coerceOrConvert :: (a -> b
最近,我在Elm中开发了一个API,其中一个主要类型是反向变体。因此,我在谷歌上搜索了一下,看看如何处理反变体类型,并发现了。
它的定义如下:
class Contravariant f => Divisible f where
divide :: (a -> (b, c)) -> f b -> f c -> f a
conquer :: f a
事实证明,我的特定类型确实适合可除类型类的定义。虽然Elm不支持类型类,但我确实不时地查看Haskell以获得一些灵感。
我的问题是:这个类型的类有什么实际用途吗?在Haskell (或其他语言)中,是否存在
我是一个Scala程序员,学习Haskell和"Haskell编程从首要原则“,使我在Scala中使用的功能概念更加一致。
我非常理解赛跑的概念。在Scala中很好地实现了它。
然而,我不理解提交人所提供的仓促和取消仓促的实施:
curry f a b = f (a, b)
:t curry
-- curry :: ((t1, t2) -> t) -> t1 -> t2 -> t
:t fst
-- fst :: (a, b) -> a
:t curry fst
-- curry fst :: t -> b -> t
uncurr
我正在编写一个小型Haskell编译器,我希望尽可能多地实现Haskell 2010。我的编译器可以解析一个模块,但是完成一个程序的模块似乎是一个非常重要的任务。我列举了一些棘手但可能有效的Haskell模块的例子:
module F(G.x) where
import F as G
x = 2
在这里,模块F导出G.x,但是G.x与F.x相同,因此模块F导出x是当且仅当它导出x的。
module A(a) where
import B(a)
a = 2
module B(a) where
import A(a)
在本例中,要解析模块A的导出,编译器必须检查从B导入的a是
(感谢Rein和Carsten对前一篇文章的建议--现在已经删除了。)
即使下面的内容在Haskell中是不寻常的,用这种方式定义前向函数组合运算符和反向应用运算符是否有效率低下或不合适的地方呢?
> let (?) f g = \x -> g (f x) -- forward function composition operator
> :t (+3) ? (*4)
> (+3) ? (*4) :: Num t => t -> t
> let x ?? f = f x -- reverse application operator
-- F