小编dfe*_*uer的帖子

如何在Ocaml中编写模式匹配以便于扩展?

我正在学习Jason Hickey的Objective Caml简介.

有这样的练习:

练习4.3假设我们有一个基于以下替换密码的加密系统,其中每个普通字母都根据下表加密.

Plain     | A B C D
--------------------
Encrypted | C A D B
Run Code Online (Sandbox Code Playgroud)

例如,字符串BAD将被加密为ACB.

编写一个函数check,给定一个明文字符串s 1和一个密文字符串s 2,true当且仅当s 2s 1的密文时才返回.如果s 1不是明文字符串,则您的函数应引发异常.您可能希望参考第8页的字符串操作.当字母表变大时,您的代码如何缩放?[强调补充]


基本上,我用might-be-stupid-naive这个练习的方法编写了两个函数.

我想首先就我的解决方案征求意见.

然后,我想询问练习中突出显示的缩放解决方案的提示.


使用if else

let check_cipher_1 s1 s2 = 
    let len1 = String.length s1 in
        let len2 = String.length s2 in              
            if len1 = len2 then
                    let rec check pos …
Run Code Online (Sandbox Code Playgroud)

ocaml functional-programming

4
推荐指数
1
解决办法
541
查看次数

是否有'span`和`fol​​dl'的优化组合,或者GHC会优化组合吗?

假设我想要列出列表中的所有元素,但不包括第一个负数,并返回数字和列表的其余部分.这样做的简单方法是

addPos l = s `seq` (s,back)
  where
    (front, back) = span (>= 0) l
    s = sum front

其中,seq应确保没有人意外通过强制和前背部建立一个巨大的thunk.

然而,我很好奇GHC是否足够智能以避免创建中间前沿列表.此外,有人可以解释(如果有的话)它会发现它可以严格累积总和吗?Prelude定义使用foldl而不是foldl',GHC定义看起来相同.

optimization haskell ghc fold

4
推荐指数
1
解决办法
162
查看次数

在Haskell有任何有趣的交换单子吗?

在我今天编辑它之前,Haskell Wiki 声称Maybe是一个可交换的monad(实际上,我认为它仍然在某个地方声称它).这显然是错误的,因为

do {a <- Nothing; b <- undefined; return (a,b)} === Nothing
Run Code Online (Sandbox Code Playgroud)

do {b <- undefined; a <- Nothing; return (a,b)} === undefined
Run Code Online (Sandbox Code Playgroud)

这种交换失败在实际代码中实际上相当重要:程序员依赖于计算一到达就会停止的事实Nothing.

这留下(在Haskell Wiki上被描述为可交换的Readermonad中)只有monad,它似乎没有做任何非常令人兴奋的事情.这引发了是否有哈斯克尔任何交换单子是基本上不同于在我脑海里的问题Reader,除了限制 Reader.

编辑

我只是意识到也可以使受限制的Writermonad成为可交换的 - 它需要在一些可交换的monoid中积累值.仍然没有意思.

monads haskell

4
推荐指数
1
解决办法
366
查看次数

如何将此过程代码设计为基于类(面向对象)?

我是初学者 - 中级自学Python开发人员,

在我完成的大多数项目中,我可以看到以下过程重复.我没有任何外部家庭代码经验,我认为下面的代码不是那么专业,因为它不可重复使用,似乎它不适合容器中的所有功能,而是在不同模块上的松散耦合功能.

def get_query():
    # returns the query string
    pass

def make_request(query):
    # makes and returns the request with query
    pass

def make_api_call(request):
    # calls the api and returns response
    pass

def process_response(response):
    # process the response and returns the details
    pass

def populate_database(details):
    # populates the database with the details and returns the status of population
    pass

def log_status(status):
    # logs the status so that developer knows whats happening
    pass

query = get_query()
request = make_request(query)
response …
Run Code Online (Sandbox Code Playgroud)

python oop class-design

4
推荐指数
3
解决办法
849
查看次数

索引向量中的类型参数的顺序

在依赖类型编程中定义似乎是常规的

data Vec :: Type -> Nat -> Type where
  Nil :: Vec a 'Z
  Cons :: a -> Vec a n -> Vec a ('S n)
Run Code Online (Sandbox Code Playgroud)

在Haskell,但是,Functor,Applicative,Foldable,Traversable,Eq1,Ord1,等,班似乎有一个良好的情况下,周边的翻转参数,来Vec :: Nat -> Type -> Type.

通常惯例有一些重要原因吗?或者它恰好是人们碰巧在不基于类型类的语言中使用的?

haskell dependent-type

4
推荐指数
1
解决办法
92
查看次数

GHCi中定义的函数中的非穷举模式

我正在尝试编写一个Erasthosthenes函数的筛子,它将用户的所有素数从2增加到他的上限.所以我写了这段代码:

main = do
putStrLn "Upper Limit"
g <- readLn
let sieve [] = []
let sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
let primes = sieve [2..g]
print primes
Run Code Online (Sandbox Code Playgroud)

代码编译并给我正确的解决方案,但我在解决方案的最后得到了这个例外:***例外:功能筛的非详尽模式所以我检查了哪些模式不匹配.

warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `sieve': Patterns not matched: (_:_)

warning: [-Wincomplete-patterns]
    Pattern match(es) are non-exhaustive
    In an equation for `sieve': Patterns not matched: []
Run Code Online (Sandbox Code Playgroud)

至极我不明白,因为我已经给了let sieve [] = [] 我以为_哈斯克尔是指任何变量,这样是什么模式(:)是什么意思?任何帮助,将不胜感激.

haskell exception ghci

4
推荐指数
1
解决办法
587
查看次数

努力实现Monad功能

最近,我正在玩Haskell monad并试图了解这个概念.

假设声明了一个可以有多个子树的树数据类型.

data MyTree a = MyTree a [MyTree a]
Run Code Online (Sandbox Code Playgroud)

而且我正在尝试实现一个函数,如果树在树中包含任何"Nothing"值,则返回"Nothing".否则,提取所有m值并返回一个包装树.

因此函数类型签名具有以下内容.

check :: Monad m => MyTree (m a) -> m (MyTree a)
Run Code Online (Sandbox Code Playgroud)

这是我目前的实施.

check (MyTree v []) = v >>= (\v' -> return (MyTree v' []))
check (MyTree v (x:xs)) =
  v >>= (\v' -> check x >>= (\t' -> return (MyTree v' [t'])))
Run Code Online (Sandbox Code Playgroud)

我在v上使用绑定运算符,以便我可以得到它的纯值.然后我用列表中的头部值递归调用"check"函数.最后,我将最终结果包装好.

我测试了一些样品并得到了以下结果.

> test1 = MyTree (Just 1) [MyTree (Just 2) [MyTree (Just 3) []]]
> check test1
Just (MyTree 1 [MyTree 2 …
Run Code Online (Sandbox Code Playgroud)

monads haskell functional-programming

4
推荐指数
1
解决办法
120
查看次数

如何反转haskell中的图形?

对于练习我需要反转图形(反转所有边缘),但我没有得到任何结果.所以我需要一些帮助.

我知道你可能不想为我解决这个问题,所以这不是我要求的.我只需要一些建议......

所以要达到它:

data Graph a = G
  { nodes :: [a]
  , successors :: a -> [a] }

reverseGraph :: Eq a => Graph a -> Graph a
Run Code Online (Sandbox Code Playgroud)

图表必须包含以下参数:节点列表和定义后继者的函数.此函数具有以下类型: a -> [a]

例如:

graph1 :: Graph Int
graph1 = G [1..6] $ \case   1 -> [2,3]
                            2 -> []
                            3 -> [1,4,6]
                            4 -> [1]
                            5 -> [3,5]
                            6 -> [2,4,5]
Run Code Online (Sandbox Code Playgroud)

反转图表将是:

reverseGraph graph1 ~>
    2 -> [1,6]
    3 -> [1,5]
    1 -> [3,4]
    4 -> [3,6]
    6 -> …
Run Code Online (Sandbox Code Playgroud)

haskell graph

4
推荐指数
1
解决办法
85
查看次数

需要多少张fmap?

Daniel Wagner 的评论使我想到了这个问题。让我们从过度简化开始。假设你有一个类型

data Foo a = Foo [a]
Run Code Online (Sandbox Code Playgroud)

然后您可以编写Functor实例

instance Functor Foo where
  fmap f (Foo l) = Foo (fmap f l)
Run Code Online (Sandbox Code Playgroud)

您可以将右侧重写为

Foo . fmap f $ l
Run Code Online (Sandbox Code Playgroud)

认识到了(->) afmap = (.)你可以把它写

fmap Foo (fmap f) l
Run Code Online (Sandbox Code Playgroud)

重复,你得到

fmap (fmap Foo) fmap f l
Run Code Online (Sandbox Code Playgroud)

所以,最后,

fmap f (Foo l) =
  fmap fmap fmap Foo fmap f l
Run Code Online (Sandbox Code Playgroud)

如果选择一个稍微复杂一点的函子怎么办?

data Bar = Bar [Maybe a]

instance Functor Bar where
  fmap f …
Run Code Online (Sandbox Code Playgroud)

haskell

4
推荐指数
1
解决办法
106
查看次数

代表无限动作链的 Monad 转换器?

我试图实现一个表示无限动作链的 monad 转换器,如下所示:

import Control.Arrow
import Control.Monad
import Data.Functor.Classes
import Data.Functor.Identity
import Data.Monoid
import Data.Semigroup
import Text.Read

import qualified Control.Monad.Trans.Class as T

newtype WhileT m a = WhileT {uncons :: m (a, WhileT m a)}

instance T.MonadTrans WhileT where
    lift m = WhileT $ do
        x <- m
        pure (x, T.lift m)

headW :: Functor m => WhileT m a -> m a
headW (WhileT m) = fmap fst m

tailW :: Functor m => WhileT m a -> m …
Run Code Online (Sandbox Code Playgroud)

monads haskell while-loop monad-transformers

4
推荐指数
1
解决办法
92
查看次数