List和cons运算符(:)在Haskell中非常常见.缺点是我们的朋友.但有时我想添加到列表的末尾.
xs `append` x = xs ++ [x]
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这不是实施它的有效方式.
我在Haskell中写了Pascal的三角形,但我不得不使用++ [x]反成语:
ptri = [1] : mkptri ptri
mkptri (row:rows) = newRow : mkptri rows
where newRow = zipWith (+) row (0:row) ++ [1]
Run Code Online (Sandbox Code Playgroud)
imho,这是一个可爱的可读Pascal的三角形和所有,但反成语让我烦恼.有人可以向我解释(并且,理想情况下,指向一个很好的教程)关于您想要有效追加到最后的情况下的惯用数据结构吗?我希望这个数据结构及其方法具有近似列表般的美感.或者,或者,向我解释为什么这种反成语对于这种情况实际上并不坏(如果你认为是这种情况).
[编辑]我最喜欢的答案是Data.Sequence,它确实具有"近似列表般的美丽".不确定我对操作所要求的严格程度.随时欢迎进一步的建议和不同的想法.
import Data.Sequence ((|>), (<|), zipWith, singleton)
import Prelude hiding (zipWith)
ptri = singleton 1 : mkptri ptri
mkptri (seq:seqs) = newRow : mkptri seqs
where newRow = zipWith (+) seq (0 <| seq) |> 1 …Run Code Online (Sandbox Code Playgroud) 我在Haskell中创建了一个函数,它只将列表中的evens减半,我遇到了问题.当我运行编译器时,它抱怨你不能执行int的划分,并且我需要一个小数int类型声明.我已经尝试将类型声明更改为float,但这只是生成了另一个错误.我已经在下面包含了该函数的代码,并希望获得任何形式的帮助.
halfEvens :: [Int] -> [Int]
halfEvens [] = []
halfEvens (x:xs) | odd x = halfEvens xs
| otherwise = x/2:halfEvens xs
Run Code Online (Sandbox Code Playgroud)
谢谢你的阅读.
如果我们将对类别的理解限制Category为Haskell中的常用类:
class Category c where
id :: c x x
(>>>) :: c x y -> c y z -> c x z
Run Code Online (Sandbox Code Playgroud)
那么让我们说a Arrow是Category另外一个:
class Category c => Arrow c where
(***) :: c x y -> c x' y' -> c (x,x') (y,y')
(&&&) :: c x y -> c x y' -> c x (y,y')
Run Code Online (Sandbox Code Playgroud)
我们可以很容易地推导出:
first :: c x y -> c (x,z) (y,z)
first a = a *** id
second …Run Code Online (Sandbox Code Playgroud) 通常当我正在使用Haskell代码时,我会使用类型注释来解决问题undefined.
foo :: String -> Int
foo = undefined
Run Code Online (Sandbox Code Playgroud)
是否存在类型级别的"未定义",我可以以类似的方式使用它?
(理想情况下,结合一种注释)
type Foo :: * -> *
type Foo = Undefined
Run Code Online (Sandbox Code Playgroud)
在同一个线程上进一步思考:有没有办法为这样创建的类型存根类型化实例?比以下理论方法更简单的方法是什么?
instance Monad Foo where
return = undefined
(>>=) = undefined
Run Code Online (Sandbox Code Playgroud) 我很困惑.我可以这样写:
import Control.Monad
main = print $ head $ (foldr (.) id [f, g]) [3]
where f = (1:)
g = undefined
Run Code Online (Sandbox Code Playgroud)
而输出是1.这是有道理的,因为它减少到:
main = print $ head $ ((1:) . undefined . id) [3]
main = print $ head $ (1:) ((undefined . id) [3])
main = print $ head $ 1 : ((undefined . id) [3])
main = print $ 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我使用模糊相似的monadic技术,它不会起作用:
import Control.Monad
main = print $ (foldr (<=<) return [f, g]) 3
where f …Run Code Online (Sandbox Code Playgroud) 我一直很喜欢Data.Sequence.但是,由于我一直在学习Data.Vector,它似乎可以做Data.Sequence可以做的一切,但更好,再加上它可以做更多的东西.我们应该弃用Data.Sequence并讲道Data.Vector吗?在Data.Vector上使用Data.Sequence有什么好的理由吗?
在Scala中使用许多较新的语言特性,可以实现可组合的组件系统,并使用所谓的Cake Pattern创建组件,Martin Odersky在可扩展组件抽象论文中以及最近的演讲中描述了这种模式.
Cake Pattern中使用的一些Scala功能具有相应的Haskell功能.例如,Scala implicits对应于Haskell类型类,Scala的抽象类型成员似乎对应于Haskell的关联类型.这让我想知道Cake Pattern是否可以在Haskell中实现以及它看起来像什么.
Cake模式可以在Haskell中实现吗?Scala功能在这样的实现中对应哪些Haskell功能?如果Cake模式无法在Haskell中实现,那么哪些语言功能可能无法实现?
这个问题出现在#haskell irc chat上:
如何在不导入前奏的情况下启动ghci?
可能的答案显而易见:
ghci -XNoImplicitPrelude,或加载文件import Prelude ()
后者似乎有效,而前者则不然.但是,import Prelude ()从Prelude导入声明的实例,对吧?有没有更好的方法来创建一个ghci会话而不加载Prelude?
我有一些代码:
object Main extends App
{
val NameTemplate = """^([A-Za-z]+)_(\d+)\.png""".r
override def main (args:Array[String])
{
// Why is NameTemplate null here?
}
}
Run Code Online (Sandbox Code Playgroud)
为什么NameTemplate不在main方法中初始化?
我正在Haskell写一个brainfuck解释器,我想出了一个我认为对程序非常有趣的描述:
data Program m = Instruction (m ()) (Program m)
| Control (m (Program m))
| Halt
Run Code Online (Sandbox Code Playgroud)
但是,将brainfuck程序的文本表示解析为此数据类型是很棘手的.尝试正确解析方括号时会出现问题,因为有一些结点可以使Instruction循环中的最终内容Control再次链接到循环.
更多初步信息.有关所有详细信息,请参阅github repo上的此版本.
type TapeM = StateT Tape IO
type TapeP = Program TapeM
type TapeC = Cont TapeP
branch :: Monad m => m Bool -> Program m -> Program m -> Program m
branch cond trueBranch falseBranch =
Control ((\b -> if b then trueBranch else falseBranch) `liftM` cond)
loopControl :: TapeP -> TapeP -> …Run Code Online (Sandbox Code Playgroud)