negate

negate

  • (predicate: Predicate) => Predicate
  1. Negate a predicate

    For example, if you pass a function that always returns true, then negate gives you a function returning false.

    const gt2 = n => n > 2
    const lte2 = negate(gt2)
    
    gt2(2) // is false
    lte2(2) // is true
    const gt2 = (n: number) => n > 2
    const lte2 = negate(gt2)
    
    gt2(2) // is false
    lte2(2) // is true
    
    const gt2 = n => n > 2
    const lte2 = negate(gt2)
    
    gt2(2) // is false
    lte2(2) // is true
    const gt2 = (n: number) => n > 2
    const lte2 = negate(gt2)
    
    gt2(2) // is false
    lte2(2) // is true
    
  2. Sometimes we want the opposite of a predicate. Below, we are writing a plugin for a chat API. We want to show a tooltip when a user cannot be messaged. Let's negate canMessage and update the users with our tooltip.

    const pluginApi = {
      canMessage: user => user.status === 'active',
      updateUsers: (updateFn, predicate) => {
        pluginApi._users.filter(predicate).forEach(updateFn)
      },
      _users: [
        {
          email: 'matt@example.com',
          status: 'away',
        },
        {
          email: 'jason@example.com',
          status: 'active',
        },
      ],
    }
    
    const cannotMessage = negate(pluginApi.canMessage)
    const addTooltip = mSet('tooltip', 'cannot message this user')
    
    pluginApi.updateUsers(addTooltip, cannotMessage)
    
    console.log(pluginApi._users)
    // is [
    //   {
    //     email: matt@example.com
    //     status: away
    //     tooltip: cannot message this user
    //   }
    //   {
    //     email: jason@example.com
    //     status: active
    //   }
    // ]
    type User = {
      email: string
      status: string
      tooltip?: string
    }
    type Predicate = (user: User) => boolean
    type UpdateFn = (user: User) => void
    
    const pluginApi = {
      canMessage: (user: User) => user.status === 'active',
      updateUsers: (updateFn: UpdateFn, predicate: Predicate) => {
        pluginApi._users.filter(predicate).forEach(updateFn)
      },
      _users: [
        {
          email: 'matt@example.com',
          status: 'away',
        },
        {
          email: 'jason@example.com',
          status: 'active',
        },
      ] as User[],
    }
    
    const cannotMessage = negate(pluginApi.canMessage)
    const addTooltip = mSet('tooltip', 'cannot message this user')<User>
    
    pluginApi.updateUsers(addTooltip, cannotMessage)
    
    console.log(pluginApi._users)
    // is [
    //   {
    //     email: matt@example.com
    //     status: away
    //     tooltip: cannot message this user
    //   }
    //   {
    //     email: jason@example.com
    //     status: active
    //   }
    // ]
    
    const pluginApi = {
      canMessage: user => user.status === 'active',
      updateUsers: (updateFn, predicate) => {
        pluginApi._users
          .filter(predicate)
          .forEach(updateFn)
      },
      _users: [
        {
          email: 'matt@example.com',
          status: 'away',
        },
        {
          email: 'jason@example.com',
          status: 'active',
        },
      ],
    }
    
    const cannotMessage = negate(pluginApi.canMessage)
    const addTooltip = mSet(
      'tooltip',
      'cannot message this user'
    )
    
    pluginApi.updateUsers(addTooltip, cannotMessage)
    
    console.log(pluginApi._users)
    // is [
    //   {
    //     email: matt@example.com
    //     status: away
    //     tooltip: cannot message this user
    //   }
    //   {
    //     email: jason@example.com
    //     status: active
    //   }
    // ]
    type User = {
      email: string
      status: string
      tooltip?: string
    }
    type Predicate = (user: User) => boolean
    type UpdateFn = (user: User) => void
    
    const pluginApi = {
      canMessage: (user: User) =>
        user.status === 'active',
      updateUsers: (
        updateFn: UpdateFn,
        predicate: Predicate
      ) => {
        pluginApi._users
          .filter(predicate)
          .forEach(updateFn)
      },
      _users: [
        {
          email: 'matt@example.com',
          status: 'away',
        },
        {
          email: 'jason@example.com',
          status: 'active',
        },
      ] as User[],
    }
    
    const cannotMessage = negate(pluginApi.canMessage)
    const addTooltip = mSet(
      'tooltip',
      'cannot message this user'
    )<User>
    
    pluginApi.updateUsers(addTooltip, cannotMessage)
    
    console.log(pluginApi._users)
    // is [
    //   {
    //     email: matt@example.com
    //     status: away
    //     tooltip: cannot message this user
    //   }
    //   {
    //     email: jason@example.com
    //     status: active
    //   }
    // ]