美文网首页
[01]-函数式思想

[01]-函数式思想

作者: 快乐捣蛋鬼 | 来源:发表于2019-06-17 15:44 被阅读0次
    屏幕快照 2019-06-17 下午3.40.33.png
    import Foundation
    
    // 定义两种类型: Distance 和 Position
    typealias Distance = Double
    
    struct Position {
        var x: Double
        var y: Double
        var length: Double {
            return sqrt(x*x + y*y)
        }
    }
    
    extension Position {
        // 用于检验一个点是否在图2.1中的灰色区域里
        func inRange(range: Distance) -> Bool {
            return sqrt(x*x + y*y) <= range
        }
        
        func minus(p: Position) -> Position {
            return Position(x: x - p.x, y: y - p.y)
        }
    }
    
    屏幕快照 2019-06-17 下午3.41.44.png
    // 允许船有自己的位置,不一定在原点,引入一个结构体,它有一个属性为 position
    struct Ship {
        var postion: Position
        var firingRange: Distance
        var unsafeRange: Distance
    }
    
    屏幕快照 2019-06-17 下午3.46.37.png 屏幕快照 2019-06-17 下午3.46.48.png
    extension Ship {
        func canEngageShip(target: Ship, friend: Ship) -> Bool {
            let dx = target.postion.x - postion.x
            let dy = target.postion.y - postion.y
            let targetDistance = sqrt(dx*dx + dy*dy)
            
            let friendDx = friend.postion.x - target.postion.x
            let friendDy = friend.postion.y - target.postion.y
            let friendDistance = sqrt(friendDx*friendDx + friendDy*friendDy)
            return targetDistance <= firingRange && targetDistance > unsafeRange && (friendDistance > unsafeRange)
            // 目标在开火范围内 && 避免与过近的敌方交战 && 避免敌方过于接近友方
        }
        
        // 添加辅助函数之后代码更清晰易读
        func canEngageShip1(target: Ship, friend: Ship) -> Bool {
            let targetDistance = target.postion.minus(p: postion).length
            let friendDistance = friend.postion.minus(p: target.postion).length
            return targetDistance <= firingRange && targetDistance > unsafeRange && (friendDistance > unsafeRange)
        }
      
    }
    

    使用 Region 类型

    // Region 类型将指代把 Position 转化为 Bool 的函数
    // 函数式编程的核心理念就是函数是值,它和结构体、整型或是布尔型没有什么区别
    typealias Region = (Position) -> Bool
    
    // summary: 使用一个能判断给定点是否在区域的函数来代表一个区域,而不是定义一个对象或结构来表示它
    
    // 定义的第一个区域: 以原点为圆心的圆(circle)
    func circle(radius: Distance) -> Region {
        return { point in point.length <= radius }
    }
    
    // 定义的第二个区域: 圆心为任意点的圆 (circle2)
    func circle2(radius: Distance, center: Position) -> Region {
        return { point in point.minus(p: center).length <= radius }
    }
    
    // 区域变换函数,按一定的偏移量移动一个区域: 可以对更多的组件(圆/矩形等)作出同样的改变
    func shift(region: @escaping Region, offset: Position) -> Region {
        return { point in region(point.minus(p: offset)) }
    }
    
    // 一个圆心为 (5, 5) 半径为 10 的圆,可以用下面的方式表示:
    shift(region: circle(radius: 10), offset: Position(x: 5, y: 5))
    
    // summary: 为了避免创建像 circle2 这样越来越复杂的函数,我们编写了一个 shift(_:offset:) 函数来改变另一个函数
    
    
    // 反转一个区域以定义另一个区域,这个新产生的区域由原区域以外的所有点组成:
    func invert(region: @escaping Region) -> Region {
        return { point in !region(point)}
    }
    
    // 计算参数中两个区域的交集
    func intersection(region1: @escaping Region, _ region2: @escaping Region) -> Region {
        return { point in region1(point) && region2(point)}
    }
    
    // 计算参数中两个区域的并集
    func union(region1: @escaping Region, region2: @escaping Region) -> Region {
        return  { point in region1(point) || region2(point)}
    }
    
    // 所有在第一个区域中但不在第二个区域中的点构成的区域:
    func difference(region1: @escaping Region, region2: @escaping Region) -> Region {
        return intersection(region1: region1, invert(region: region2))
        
    }
    
    extension Ship {
        // 将一些小型函数装配起来, 使用 Region 函数重构
        func canEngageShip2(target: Ship, friend: Ship) -> Bool {
            let safeRegion = difference(region1: circle(radius: firingRange), region2: circle(radius: unsafeRange))
            let firingRegion = shift(region: safeRegion, offset: postion)
            let friendRegion = shift(region: circle(radius: unsafeRange), offset: friend.postion)
            let resultRegion = difference(region1: firingRegion, region2: friendRegion)
            return resultRegion(target.postion)
        }
    }
    

    完整代码

    import Foundation
    
    // 定义两种类型: Distance 和 Position
    typealias Distance = Double
    
    struct Position {
        var x: Double
        var y: Double
        var length: Double {
            return sqrt(x*x + y*y)
        }
    }
    
    extension Position {
        // 用于检验一个点是否在图2.1中的灰色区域里
        func inRange(range: Distance) -> Bool {
            return sqrt(x*x + y*y) <= range
        }
        
        func minus(p: Position) -> Position {
            return Position(x: x - p.x, y: y - p.y)
        }
    }
    
    // 允许船有自己的位置,不一定在原点,引入一个结构体,它有一个属性为 position
    struct Ship {
        var postion: Position
        var firingRange: Distance
        var unsafeRange: Distance
    }
    
    extension Ship {
        func canEngageShip(target: Ship, friend: Ship) -> Bool {
            let dx = target.postion.x - postion.x
            let dy = target.postion.y - postion.y
            let targetDistance = sqrt(dx*dx + dy*dy)
            
            let friendDx = friend.postion.x - target.postion.x
            let friendDy = friend.postion.y - target.postion.y
            let friendDistance = sqrt(friendDx*friendDx + friendDy*friendDy)
            return targetDistance <= firingRange && targetDistance > unsafeRange && (friendDistance > unsafeRange)
            // 目标在开火范围内 && 避免与过近的敌方交战 && 避免敌方过于接近友方
        }
        
        // 添加辅助函数之后代码更清晰易读
        func canEngageShip1(target: Ship, friend: Ship) -> Bool {
            let targetDistance = target.postion.minus(p: postion).length
            let friendDistance = friend.postion.minus(p: target.postion).length
            return targetDistance <= firingRange && targetDistance > unsafeRange && (friendDistance > unsafeRange)
        }
      
    }
    
    // Region 类型将指代把 Position 转化为 Bool 的函数
    // 函数式编程的核心理念就是函数是值,它和结构体、整型或是布尔型没有什么区别
    typealias Region = (Position) -> Bool
    
    // summary: 使用一个能判断给定点是否在区域的函数来代表一个区域,而不是定义一个对象或结构来表示它
    
    // 定义的第一个区域: 以原点为圆心的圆(circle)
    func circle(radius: Distance) -> Region {
        return { point in point.length <= radius }
    }
    
    // 定义的第二个区域: 圆心为任意点的圆 (circle2)
    func circle2(radius: Distance, center: Position) -> Region {
        return { point in point.minus(p: center).length <= radius }
    }
    
    // 区域变换函数,按一定的偏移量移动一个区域: 可以对更多的组件(圆/矩形等)作出同样的改变
    func shift(region: @escaping Region, offset: Position) -> Region {
        return { point in region(point.minus(p: offset)) }
    }
    
    // 一个圆心为 (5, 5) 半径为 10 的圆,可以用下面的方式表示:
    shift(region: circle(radius: 10), offset: Position(x: 5, y: 5))
    
    // summary: 为了避免创建像 circle2 这样越来越复杂的函数,我们编写了一个 shift(_:offset:) 函数来改变另一个函数
    
    
    // 反转一个区域以定义另一个区域,这个新产生的区域由原区域以外的所有点组成:
    func invert(region: @escaping Region) -> Region {
        return { point in !region(point)}
    }
    
    // 计算参数中两个区域的交集
    func intersection(region1: @escaping Region, _ region2: @escaping Region) -> Region {
        return { point in region1(point) && region2(point)}
    }
    
    // 计算参数中两个区域的并集
    func union(region1: @escaping Region, region2: @escaping Region) -> Region {
        return  { point in region1(point) || region2(point)}
    }
    
    // 所有在第一个区域中但不在第二个区域中的点构成的区域:
    func difference(region1: @escaping Region, region2: @escaping Region) -> Region {
        return intersection(region1: region1, invert(region: region2))
        
    }
    
    extension Ship {
        // 将一些小型函数装配起来, 使用 Region 函数重构
        func canEngageShip2(target: Ship, friend: Ship) -> Bool {
            let safeRegion = difference(region1: circle(radius: firingRange), region2: circle(radius: unsafeRange))
            let firingRegion = shift(region: safeRegion, offset: postion)
            let friendRegion = shift(region: circle(radius: unsafeRange), offset: friend.postion)
            let resultRegion = difference(region1: firingRegion, region2: friendRegion)
            return resultRegion(target.postion)
        }
    }
    
    
    //          ___
    //        //|||\\
    //       //|-_-|\\
    //          |||
    //           |
    //           |
    //          / \
    
    

    相关文章

      网友评论

          本文标题:[01]-函数式思想

          本文链接:https://www.haomeiwen.com/subject/vegafctx.html